Hello community,

here is the log from the commit of package uwsgi for openSUSE:Factory checked 
in at 2020-11-29 12:29:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/uwsgi (Old)
 and      /work/SRC/openSUSE:Factory/.uwsgi.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "uwsgi"

Sun Nov 29 12:29:30 2020 rev:39 rq:851302 version:2.0.19.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/uwsgi/uwsgi.changes      2020-09-21 
17:26:17.616077832 +0200
+++ /work/SRC/openSUSE:Factory/.uwsgi.new.5913/uwsgi.changes    2020-11-29 
12:29:31.734068970 +0100
@@ -1,0 +2,38 @@
+Thu Nov 26 18:51:29 UTC 2020 - Dirk Mueller <[email protected]>
+
+- update 2.0.19.1:
+  * Reverted CGI chunked encoding support
+  * Fixed bug with WSGI responses returning 
+  * Update travis to xenial (Terence D. Honles)
+  * Fix segfault in logsocket plugin (Riccardo Magliocchetti, #2010)
+  * Backport Coverity fixes from master (Riccardo Magliocchetti)
+  * Fix Python 3.7 warnings (Orivej Desh)
+  * Fix uwsgi.workers() leak in Python plugin (Arne Welzel, #2056)
+  * Backport redislog plugin 32-bit build fixes (Riccardo Magliocchetti, #1828)
+  * Fix stack overflow in core/rpc (Nicola Martino)
+  * Fix build with spaces in the path (Arne Welzel, #1939)
+  * Add missing initialization for zend_file_handle in php plugin (Arne Welzel)
+  * Build Python 3.7 and 3.8 plugins in CI (Arne Welzel)
+  * Add Trove classifiers for Python 3.7 and 3.8 (Hugo)
+  * Graceful shutdown for vassals (Sponsored by guppyltd.com)
+  * Improve yaml parsing with libyaml (Arne Welzel, #2097)
+  * Add smart-daemon2 option to notify daemon of master reloading (Eduardo 
Felipe Castegnaro)
+  * Do not chroot multiple times when root (Arne Welzel)
+  * Support io.BytesIO with wsgi.file_wrapper (Arne Welzel, #1126)
+  * Add websocket continuation frames support (Timi, #1350)
+  * Fix compilation with gevent 1.5.0 (Vytautas Liuolia)
+  * Fix PSGI plugin build with gcc 10 (Jorge Gallegos)
+  * Get rid of paste.script dependency in pypy/python plugins (Thomas De 
Schampheleire)
+  * Improve performance for santitizing file descriptors with cgi plugin 
(Natanael Copa, #2053)
+  * Fix offload-threads with honour-range (Liss Tarnell)
+  * Fix logging packet size length overflow (Pawel Marokwsi)
+  * Fix possible deadlock in install (Jacob Tolar)
+  * Fix parsing of http port for ipv6 (Cyril Baÿ)
+  * Fix impossibility of determining the end of the chunked stream with psgi 
plugin (ols)
+  * Fix parsing of http-socket port for ipv6 (Daniel Holth)
+  * Add chunked request decoding to the CGI plugin (Robert Schindler)
+  * Add add max-worker-lifetime-delta to reload workers with a delta (Marcin 
Lulek , #2020)
+
+- remove uwsgi-2.0.18-psgi-fix-duplicate-uperl.patch (upstream)
+
+-------------------------------------------------------------------

Old:
----
  uwsgi-2.0.18-psgi-fix-duplicate-uperl.patch
  uwsgi-2.0.18.tar.gz

New:
----
  uwsgi-2.0.19.1.tar.gz

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

Other differences:
------------------
++++++ uwsgi.spec ++++++
--- /var/tmp/diff_new_pack.B3JCiD/_old  2020-11-29 12:29:32.494069739 +0100
+++ /var/tmp/diff_new_pack.B3JCiD/_new  2020-11-29 12:29:32.498069744 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           uwsgi
-Version:        2.0.18
+Version:        2.0.19.1
 Release:        0
 Summary:        Application Container Server for Networked/Clustered Web 
Applications
 License:        Apache-2.0 AND GPL-2.0-only WITH GCC-exception-2.0
@@ -43,8 +43,6 @@
 Patch3:         uwsgi-1.9.11-systemd_logger-old_systemd.patch
 # PATCH-FIX-OPENSUSE uwsgi-2.0.18-postgresql-config.patch - Use pkg-config 
instead of pg_config
 Patch4:         uwsgi-2.0.18-postgresql-config.patch
-# PATCH-FIX-OPENSUSE uwsgi-2.0.18-psgi-fix-duplicate-uperl.patch - Fix 
duplicate uperl with gcc 10
-Patch5:         uwsgi-2.0.18-psgi-fix-duplicate-uperl.patch
 %define apache_branch     %(rpm -q --qf %%{version} apache2 | grep -E -o 
"2\\.[0-9]+")
 %if "%{apache_branch}" == "2.4"
   %define apxs %{_bindir}/apxs2
@@ -439,7 +437,6 @@
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
-%patch5 -p1
 # Generate a config that builds all plugins except for examples and stuff we
 # can't satisfy the requirements for or are just broken
 excluded_plugins=""

++++++ uwsgi-2.0.18.tar.gz -> uwsgi-2.0.19.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/.travis.yml 
new/uwsgi-2.0.19.1/.travis.yml
--- old/uwsgi-2.0.18/.travis.yml        2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/.travis.yml      2020-06-17 11:03:34.000000000 +0200
@@ -1,3 +1,5 @@
+dist: xenial
+
 language: c
 
 compiler:
@@ -23,6 +25,12 @@
   - echo -e "\n\n>>> Building python36 plugin"
   - /usr/bin/python3.6 -V
   - /usr/bin/python3.6 uwsgiconfig.py --plugin plugins/python base python36
+  - echo -e "\n\n>>> Building python37 plugin"
+  - /usr/bin/python3.7 -V
+  - /usr/bin/python3.7 uwsgiconfig.py --plugin plugins/python base python37
+  - echo -e "\n\n>>> Building python38 plugin"
+  - /usr/bin/python3.8 -V
+  - /usr/bin/python3.8 uwsgiconfig.py --plugin plugins/python base python38
   - echo -e "\n\n>>> Building rack plugin"
   - rvm use 2.4
   - ruby -v
@@ -35,10 +43,13 @@
   - ./tests/travis.sh
 
 before_install:
+  - sudo apt-get update -qq
+  - sudo apt-get install -qqyf software-properties-common
   - sudo add-apt-repository ppa:deadsnakes/ppa -y
   - sudo add-apt-repository ppa:ondrej/php -y
   - sudo apt-get update -qq
-  - sudo apt-get install -qqyf python2.6-dev python3.4-dev python3.5-dev 
python3.6-dev
+  - sudo apt-get install -qqyf python{2.6,3.4,3.5,3.6,3.7,3.8}-dev
+  - sudo apt-get install -qqyf python3.8-distutils
   - sudo apt-get install -qqyf libxml2-dev libpcre3-dev libcap2-dev
   - sudo apt-get install -qqyf php7.2-dev libphp7.2-embed libargon2-0-dev 
libsodium-dev
   - sudo apt-get install -qqyf liblua5.1-0-dev
@@ -49,6 +60,6 @@
   - sudo apt-get install -qqyf libwrap0-dev libgeoip-dev libv8-dev libxslt1-dev
   - sudo apt-get install -qqyf libboost-thread-dev libboost-filesystem-dev
   - sudo apt-get install -qqyf libssl-dev libacl1-dev python-greenlet-dev
-  - sudo apt-get install -qqyf openjdk-7-jdk libgloox-dev gccgo
+  - sudo apt-get install -qqyf openjdk-8-jdk libgloox-dev gccgo
   - sudo apt-get install -qqyf cli-common-dev mono-devel mono-mcs uuid-dev
   - sudo apt-get install -qqyf curl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/CONTRIBUTORS 
new/uwsgi-2.0.19.1/CONTRIBUTORS
--- old/uwsgi-2.0.18/CONTRIBUTORS       2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/CONTRIBUTORS     2020-06-17 11:03:34.000000000 +0200
@@ -32,3 +32,7 @@
 Adriano Di Luzio ([email protected])
 Curtis Maloney
 Vladimir Didenko
+Alexandre Bonnetain
+Darvame Hleran
+Sokolov Yura <[email protected]>
+Marcin Lulek <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/PKG-INFO new/uwsgi-2.0.19.1/PKG-INFO
--- old/uwsgi-2.0.18/PKG-INFO   2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/PKG-INFO 2020-06-17 11:03:34.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: uWSGI
-Version: 2.0.18
+Version: 2.0.19.1
 Summary: The uWSGI server
 Home-page: https://uwsgi-docs.readthedocs.io/en/latest/
 Author: Unbit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/daemons.c 
new/uwsgi-2.0.19.1/core/daemons.c
--- old/uwsgi-2.0.18/core/daemons.c     2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/daemons.c   2020-06-17 11:03:34.000000000 +0200
@@ -254,6 +254,16 @@
                        // unregister daemon to prevent it from being respawned
                        ud->registered = 0;
                }
+
+               // smart daemons that have to be notified when master is 
reloading or stopping
+               if (ud->notifypid && ud->pid > 0 && ud->pidfile) {
+                       if (uwsgi_instance_is_reloading) {
+                               kill(-(ud->pid), ud->reload_signal > 0 ? 
ud->reload_signal : SIGHUP);
+                       }
+                       else {
+                               kill(-(ud->pid), ud->stop_signal);
+                       }
+               }
                ud = ud->next;
        }
 }
@@ -520,6 +530,7 @@
        char *d_ns_pid = NULL;
        char *d_chdir = NULL;
        char *d_max_throttle = NULL;
+       char *d_notifypid = NULL;
 
        char *arg = uwsgi_str(value);
 
@@ -543,6 +554,7 @@
                "ns_pid", &d_ns_pid,    
                "chdir", &d_chdir,      
                "max_throttle", &d_max_throttle,        
+               "notifypid", &d_notifypid,
        NULL)) {
                uwsgi_log("invalid --%s keyval syntax\n", opt);
                exit(1);
@@ -594,6 +606,8 @@
 
        uwsgi_ud->max_throttle = d_max_throttle ? atoi(d_max_throttle) : 0;
 
+       uwsgi_ud->notifypid = d_notifypid ? 1 : 0;
+
        if (d_touch) {
                size_t i,rlen = 0;
                char **argv = uwsgi_split_quoted(d_touch, strlen(d_touch), ";", 
&rlen);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/emperor.c 
new/uwsgi-2.0.19.1/core/emperor.c
--- old/uwsgi-2.0.18/core/emperor.c     2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/emperor.c   2020-06-17 11:03:34.000000000 +0200
@@ -722,7 +722,7 @@
        // remove uWSGI instance
 
        if (c_ui->pid != -1) {
-               if (write(c_ui->pipe[0], "\0", 1) != 1) {
+               if (write(c_ui->pipe[0], uwsgi.emperor_graceful_shutdown ? "\2" 
: "\0", 1) != 1) {
                        uwsgi_error("emperor_stop()/write()");
                }
        }
@@ -739,7 +739,7 @@
        // remove uWSGI instance
 
        if (c_ui->pid != -1) {
-               if (write(c_ui->pipe[0], "\0", 1) != 1) {
+               if (write(c_ui->pipe[0], uwsgi.emperor_graceful_shutdown ? "\2" 
: "\0", 1) != 1) {
                        uwsgi_error("emperor_stop()/write()");
                }
        }
@@ -2410,8 +2410,9 @@
                if (byte == 0) {
                        uwsgi_hooks_run(uwsgi.hook_emperor_stop, 
"emperor-stop", 0);
                        close(uwsgi.emperor_fd);
-                       if (!uwsgi.status.brutally_reloading)
+                       if (!uwsgi.status.brutally_reloading && 
!uwsgi.status.brutally_destroying) {
                                kill_them_all(0);
+                       }
                }
                // reload me
                else if (byte == 1) {
@@ -2422,6 +2423,14 @@
                        grace_them_all(0);
                        uwsgi_unblock_signal(SIGHUP);
                }
+               // remove me gracefully
+               else if (byte == 2) {
+                       uwsgi_hooks_run(uwsgi.hook_emperor_stop, 
"emperor-stop", 0);
+                       close(uwsgi.emperor_fd);
+                       if (!uwsgi.status.brutally_reloading && 
!uwsgi.status.brutally_destroying) {
+                               gracefully_kill_them_all(0);
+                       }
+               }
        }
 #ifdef UWSGI_EVENT_USE_PORT
         // special cose for port event system
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/fifo.c 
new/uwsgi-2.0.19.1/core/fifo.c
--- old/uwsgi-2.0.18/core/fifo.c        2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/fifo.c      2020-06-17 11:03:34.000000000 +0200
@@ -104,7 +104,9 @@
 
        char *path = uwsgi_fifo_by_slot();
 
-       unlink(path);
+       if (unlink(path) != 0 && errno != ENOENT) {
+               uwsgi_error("uwsgi_master_fifo()/unlink()");
+       }
 
        if (mkfifo(path, S_IRUSR|S_IWUSR)) {
                uwsgi_error("uwsgi_master_fifo()/mkfifo()");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/logging.c 
new/uwsgi-2.0.19.1/core/logging.c
--- old/uwsgi-2.0.18/core/logging.c     2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/logging.c   2020-06-17 11:03:34.000000000 +0200
@@ -752,10 +752,11 @@
                i = fscanf(procfile, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s 
%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %llu %lld", (unsigned long long 
*) vsz, (unsigned long long *) rss);
                if (i != 2) {
                        uwsgi_log("warning: invalid record in 
/proc/self/stat\n");
+               } else {
+                       *rss = *rss * uwsgi.page_size;
                }
                fclose(procfile);
        }
-       *rss = *rss * uwsgi.page_size;
 #elif defined(__CYGWIN__)
        // same as Linux but rss is not in pages...
        FILE *procfile;
@@ -1082,19 +1083,18 @@
        return strlen(*buf);
 }
 
-
 static ssize_t uwsgi_lf_rsize(struct wsgi_request *wsgi_req, char **buf) {
-       *buf = uwsgi_num2str(wsgi_req->response_size);
+       *buf = uwsgi_size2str(wsgi_req->response_size);
        return strlen(*buf);
 }
 
 static ssize_t uwsgi_lf_hsize(struct wsgi_request *wsgi_req, char **buf) {
-       *buf = uwsgi_num2str(wsgi_req->headers_size);
+       *buf = uwsgi_size2str(wsgi_req->headers_size);
        return strlen(*buf);
 }
 
 static ssize_t uwsgi_lf_size(struct wsgi_request *wsgi_req, char **buf) {
-       *buf = uwsgi_num2str(wsgi_req->headers_size+wsgi_req->response_size);
+       *buf = uwsgi_size2str(wsgi_req->headers_size+wsgi_req->response_size);
        return strlen(*buf);
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/master_checks.c 
new/uwsgi-2.0.19.1/core/master_checks.c
--- old/uwsgi-2.0.18/core/master_checks.c       2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/core/master_checks.c     2020-06-17 11:03:34.000000000 
+0200
@@ -218,7 +218,7 @@
                // check if worker was running longer than allowed lifetime
                if (uwsgi.workers[i].pid > 0 && uwsgi.workers[i].cheaped == 0 
&& uwsgi.max_worker_lifetime > 0) {
                        uint64_t lifetime = uwsgi_now() - 
uwsgi.workers[i].last_spawn;
-                       if (lifetime > uwsgi.max_worker_lifetime && 
uwsgi.workers[i].manage_next_request == 1) {
+                       if (lifetime > (uwsgi.max_worker_lifetime + (i-1) * 
uwsgi.max_worker_lifetime_delta)  && uwsgi.workers[i].manage_next_request == 1) 
{
                                uwsgi_log("worker %d lifetime reached, it was 
running for %llu second(s)\n", i, (unsigned long long) lifetime);
                                uwsgi.workers[i].manage_next_request = 0;
                                kill(uwsgi.workers[i].pid, SIGWINCH);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/offload.c 
new/uwsgi-2.0.19.1/core/offload.c
--- old/uwsgi-2.0.18/core/offload.c     2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/offload.c   2020-06-17 11:03:34.000000000 +0200
@@ -671,11 +671,12 @@
        uwsgi.offload_engine_pipe = uwsgi_offload_register_engine("pipe", 
u_offload_pipe_prepare, u_offload_pipe_do);
 }
 
-int uwsgi_offload_request_sendfile_do(struct wsgi_request *wsgi_req, int fd, 
size_t len) {
+int uwsgi_offload_request_sendfile_do(struct wsgi_request *wsgi_req, int fd, 
size_t pos, size_t len) {
        struct uwsgi_offload_request uor;
        uwsgi_offload_setup(uwsgi.offload_engine_sendfile, &uor, wsgi_req, 1);
        uor.fd = fd;
        uor.len = len;
+       uor.pos = pos;
        return uwsgi_offload_run(wsgi_req, &uor, NULL);
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/rpc.c new/uwsgi-2.0.19.1/core/rpc.c
--- old/uwsgi-2.0.18/core/rpc.c 2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/rpc.c       2020-06-17 11:03:34.000000000 +0200
@@ -12,6 +12,11 @@
                return -1;
        }
 
+       if (strlen(name) >= UMAX8)  {
+             uwsgi_log("the supplied RPC name string is too long, max size is 
%d\n", UMAX8-1);
+             return -1;
+       }
+
        uwsgi_lock(uwsgi.rpc_table_lock);
 
        // first check if a function is already registered
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/utils.c 
new/uwsgi-2.0.19.1/core/utils.c
--- old/uwsgi-2.0.18/core/utils.c       2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/utils.c     2020-06-17 11:03:34.000000000 +0200
@@ -585,13 +585,15 @@
                }
        }
 
-       if (uwsgi.chroot && !uwsgi.reloads) {
+       if (uwsgi.chroot && !uwsgi.is_chrooted && !uwsgi.reloads) {
                if (!uwsgi.master_as_root)
                        uwsgi_log("chroot() to %s\n", uwsgi.chroot);
+
                if (chroot(uwsgi.chroot)) {
                        uwsgi_error("chroot()");
                        exit(1);
                }
+               uwsgi.is_chrooted = 1;
 #ifdef __linux__
                if (uwsgi.logging_options.memory_report) {
                        uwsgi_log("*** Warning, on linux system you have to 
bind-mount the /proc fs in your chroot to get memory debug/report.\n");
@@ -989,7 +991,7 @@
        return;
 
 nonroot:
-       if (uwsgi.chroot && !uwsgi.is_a_reload) {
+       if (uwsgi.chroot && !uwsgi.is_chrooted && !uwsgi.is_a_reload) {
                uwsgi_log("cannot chroot() as non-root user\n");
                exit(1);
        }
@@ -1920,6 +1922,12 @@
        return str;
 }
 
+char *uwsgi_size2str(size_t num) {
+       char *str = uwsgi_malloc(sizeof(UMAX64_STR) + 1);
+       snprintf(str, sizeof(UMAX64_STR) + 1, "%llu", (unsigned long long) num);
+       return str;
+}
+
 int uwsgi_num2str2(int num, char *ptr) {
 
        return snprintf(ptr, 11, "%d", num);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/uwsgi.c 
new/uwsgi-2.0.19.1/core/uwsgi.c
--- old/uwsgi-2.0.18/core/uwsgi.c       2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/uwsgi.c     2020-06-17 11:03:34.000000000 +0200
@@ -239,6 +239,7 @@
 #if defined(__linux__) && !defined(OBSOLETE_LINUX_KERNEL)
        {"emperor-use-clone", required_argument, 0, "use clone() instead of 
fork() passing the specified unshare() flags", uwsgi_opt_set_unshare, 
&uwsgi.emperor_clone, 0},
 #endif
+       {"emperor-graceful-shutdown", no_argument, 0, "use vassals graceful 
shutdown during ragnarok", uwsgi_opt_true, &uwsgi.emperor_graceful_shutdown, 0},
 #ifdef UWSGI_CAP
        {"emperor-cap", required_argument, 0, "set vassals capability", 
uwsgi_opt_set_emperor_cap, NULL, 0},
        {"vassals-cap", required_argument, 0, "set vassals capability", 
uwsgi_opt_set_emperor_cap, NULL, 0},
@@ -275,6 +276,7 @@
        {"max-requests", required_argument, 'R', "reload workers after the 
specified amount of managed requests", uwsgi_opt_set_64bit, 
&uwsgi.max_requests, 0},
        {"min-worker-lifetime", required_argument, 0, "number of seconds worker 
must run before being reloaded (default is 60)", uwsgi_opt_set_64bit, 
&uwsgi.min_worker_lifetime, 0},
        {"max-worker-lifetime", required_argument, 0, "reload workers after the 
specified amount of seconds (default is disabled)", uwsgi_opt_set_64bit, 
&uwsgi.max_worker_lifetime, 0},
+       {"max-worker-lifetime-delta", required_argument, 0, "add (worker_id * 
delta) seconds to the max_worker_lifetime value of each worker", 
uwsgi_opt_set_int, &uwsgi.max_worker_lifetime_delta, 0},
 
        {"socket-timeout", required_argument, 'z', "set internal sockets 
timeout", uwsgi_opt_set_int, &uwsgi.socket_timeout, 0},
        {"no-fd-passing", no_argument, 0, "disable file descriptor passing", 
uwsgi_opt_true, &uwsgi.no_fd_passing, 0},
@@ -3301,7 +3303,7 @@
        uwsgi_log_verbose("mem-collector thread started for worker %d\n", 
uwsgi.mywid);
        for(;;) {
                sleep(uwsgi.mem_collector_freq);
-               uint64_t rss, vsz;
+               uint64_t rss = 0, vsz = 0;
                get_memusage(&rss, &vsz);
                uwsgi.workers[uwsgi.mywid].rss_size = rss;
                uwsgi.workers[uwsgi.mywid].vsz_size = vsz;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/websockets.c 
new/uwsgi-2.0.19.1/core/websockets.c
--- old/uwsgi-2.0.18/core/websockets.c  2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/websockets.c        2020-06-17 11:03:34.000000000 
+0200
@@ -144,6 +144,7 @@
 static void uwsgi_websocket_parse_header(struct wsgi_request *wsgi_req) {
        uint8_t byte1 = wsgi_req->websocket_buf->buf[0];
        uint8_t byte2 = wsgi_req->websocket_buf->buf[1];
+       wsgi_req->websocket_is_fin = byte1 >> 7;
        wsgi_req->websocket_opcode = byte1 & 0xf;
        wsgi_req->websocket_has_mask = byte2 >> 7;
        wsgi_req->websocket_size = byte2 & 0x7f;
@@ -161,14 +162,38 @@
                }
        }
 
-       struct uwsgi_buffer *ub = uwsgi_buffer_new(wsgi_req->websocket_size);
+       struct uwsgi_buffer *ub = NULL;
+       if (wsgi_req->websocket_opcode == 0) {
+               if (uwsgi.websockets_continuation_buffer == NULL) {
+                       uwsgi_log("Error continuation with empty previous 
buffer");
+                       goto error;
+               }
+               ub = uwsgi.websockets_continuation_buffer;
+       }
+       else {
+               ub = uwsgi_buffer_new(wsgi_req->websocket_size);
+       }
        if (uwsgi_buffer_append(ub, (char *) ptr, wsgi_req->websocket_size)) 
goto error;        
        if (uwsgi_buffer_decapitate(wsgi_req->websocket_buf, 
wsgi_req->websocket_pktsize)) goto error;
        wsgi_req->websocket_phase = 0;
        wsgi_req->websocket_need = 2;
+
+       if (wsgi_req->websocket_is_fin) {
+               uwsgi.websockets_continuation_buffer = NULL;
+               /// Freeing websockets_continuation_buffer is done by the caller
+               return ub;
+       }
+       uwsgi.websockets_continuation_buffer = ub;
+       /// Message is not complete, send empty dummy buffer to signal waiting 
for full message
+       ub = uwsgi_buffer_new(1);
+       uwsgi_buffer_append(ub, "\0", 1);
        return ub;
 error:
        uwsgi_buffer_destroy(ub);
+       if (uwsgi.websockets_continuation_buffer != NULL && ub != 
uwsgi.websockets_continuation_buffer) {
+               uwsgi_buffer_destroy(uwsgi.websockets_continuation_buffer);
+       }
+       uwsgi.websockets_continuation_buffer = NULL;
        return NULL;
 }
 
@@ -338,12 +363,20 @@
        return NULL;
 }
 
+static void clear_continuation_buffer() {
+       if (uwsgi.websockets_continuation_buffer != NULL) {
+               uwsgi_buffer_destroy(uwsgi.websockets_continuation_buffer);
+               uwsgi.websockets_continuation_buffer = NULL;
+       }
+}
+
 struct uwsgi_buffer *uwsgi_websocket_recv(struct wsgi_request *wsgi_req) {
        if (wsgi_req->websocket_closed) {
                return NULL;
        }
        struct uwsgi_buffer *ub = uwsgi_websocket_recv_do(wsgi_req, 0);
        if (!ub) {
+               clear_continuation_buffer();
                wsgi_req->websocket_closed = 1;
        }
        return ub;
@@ -355,6 +388,7 @@
         }
         struct uwsgi_buffer *ub = uwsgi_websocket_recv_do(wsgi_req, 1);
         if (!ub) {
+               clear_continuation_buffer();
                 wsgi_req->websocket_closed = 1;
         }
         return ub;
@@ -432,4 +466,5 @@
        uwsgi.websockets_ping_freq = 30;
        uwsgi.websockets_pong_tolerance = 3;
        uwsgi.websockets_max_size = 1024;
+       uwsgi.websockets_continuation_buffer = NULL;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/writer.c 
new/uwsgi-2.0.19.1/core/writer.c
--- old/uwsgi-2.0.18/core/writer.c      2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/writer.c    2020-06-17 11:03:34.000000000 +0200
@@ -634,7 +634,7 @@
                        fd = tmp_fd;
                        can_close = 1;
                }
-                       if (!uwsgi_offload_request_sendfile_do(wsgi_req, fd, 
len)) {
+               if (!uwsgi_offload_request_sendfile_do(wsgi_req, fd, pos, len)) 
{
                        wsgi_req->via = UWSGI_VIA_OFFLOAD;
                        wsgi_req->response_size += len;
                         return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/core/yaml.c 
new/uwsgi-2.0.19.1/core/yaml.c
--- old/uwsgi-2.0.18/core/yaml.c        2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/core/yaml.c      2020-06-17 11:03:34.000000000 +0200
@@ -156,44 +156,49 @@
                        break;
                case YAML_FLOW_SEQUENCE_START_TOKEN:
                case YAML_BLOCK_SEQUENCE_START_TOKEN:
-                       status = 3;
+                       if (in_uwsgi_section)
+                               in_uwsgi_section++;
+                       // fallthrough
+               case YAML_FLOW_ENTRY_TOKEN:
+               case YAML_BLOCK_ENTRY_TOKEN:
+                       status = 3;  // inside a sequence
                        break;
                case YAML_BLOCK_MAPPING_START_TOKEN:
-                       if (!in_uwsgi_section) {
-                               if (key) {
-                                       if (!strcmp(section_asked, key)) {
-                                               in_uwsgi_section = 1;
-                                       }
+                       if (in_uwsgi_section) {
+                               in_uwsgi_section++;
+                               break;
+                       }
+                       if (key) {
+                               if (!strcmp(section_asked, key)) {
+                                       in_uwsgi_section = 1;
                                }
                        }
                        break;
                case YAML_BLOCK_END_TOKEN:
-                       if (in_uwsgi_section) {
-                               parsing = 0;
-                               break;
-                       }
+               case YAML_FLOW_SEQUENCE_END_TOKEN:
+                       if (in_uwsgi_section)
+                               parsing = !!(--in_uwsgi_section);
+                       key = NULL;
+                       status = 0;
                        break;
                case YAML_SCALAR_TOKEN:
-               case YAML_FLOW_ENTRY_TOKEN:
-               case YAML_BLOCK_ENTRY_TOKEN:
                        if (status == 1) {
                                key = (char *) token.data.scalar.value;
                        }
-                       else if (status == 2) {
+                       else if (status == 2 || status == 3) {
                                val = (char *) token.data.scalar.value;
                                if (key && val && in_uwsgi_section) {
                                        add_exported_option(key, val, 0);
                                }
-                               status = 0;
-                       }
-                       else if (status == 3) {
-                               val = (char *) token.data.scalar.value;
-                               if (key && val && in_uwsgi_section) {
-                                       add_exported_option(key, val, 0);
+
+                               // If this was the scalar of a value token, 
forget the state.
+                               if (status == 2) {
+                                       key = NULL;
+                                       status = 0;
                                }
                        }
                        else {
-                               uwsgi_log("unsupported YAML token in %s 
block\n", section_asked);
+                               uwsgi_log("unsupported YAML token %d in %s 
block\n", token.type, section_asked);
                                parsing = 0;
                                break;
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/cgi/cgi_plugin.c 
new/uwsgi-2.0.19.1/plugins/cgi/cgi_plugin.c
--- old/uwsgi-2.0.18/plugins/cgi/cgi_plugin.c   2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/plugins/cgi/cgi_plugin.c 2020-06-17 11:03:34.000000000 
+0200
@@ -780,8 +780,21 @@
        close(cgi_pipe[1]);
 
        // close all the fd > 2
-       for(i=3;i<(int)uwsgi.max_fd;i++) {
-               close(i);
+       DIR *dirp = opendir("/proc/self/fd");
+       if (dirp == NULL)
+               dirp = opendir("/dev/fd");
+       if (dirp != NULL) {
+               struct dirent *dent;
+               while ((dent = readdir(dirp)) != NULL) {
+                       int fd = atoi(dent->d_name);
+                       if ((fd > 2) && fd != dirfd(dirp))
+                               close(fd);
+               }
+               closedir(dirp);
+       } else {
+               for(i=3;i<(int)uwsgi.max_fd;i++) {
+                       close(i);
+               }
        }
 
        // fill cgi env
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/corerouter/cr_common.c 
new/uwsgi-2.0.19.1/plugins/corerouter/cr_common.c
--- old/uwsgi-2.0.18/plugins/corerouter/cr_common.c     2019-02-09 
15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/plugins/corerouter/cr_common.c   2020-06-17 
11:03:34.000000000 +0200
@@ -62,7 +62,7 @@
 
                                // fix SERVER_PORT
                                if (!ugs->port || !ugs->port_len) {
-                                       ugs->port = strchr(ugs->name, ':');
+                                       ugs->port = strrchr(ugs->name, ':');
                                        if (ugs->port) {
                                                ugs->port++;
                                                ugs->port_len = 
strlen(ugs->port);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/gevent/gevent.c 
new/uwsgi-2.0.19.1/plugins/gevent/gevent.c
--- old/uwsgi-2.0.18/plugins/gevent/gevent.c    2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/plugins/gevent/gevent.c  2020-06-17 11:03:34.000000000 
+0200
@@ -433,8 +433,13 @@
        ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
        if (!ugevent.spawn) uwsgi_pyexit;
 
-       ugevent.signal = PyDict_GetItemString(gevent_dict, "signal");
-       if (!ugevent.signal) uwsgi_pyexit;
+       ugevent.signal = PyDict_GetItemString(gevent_dict, "signal_handler");
+       if (!ugevent.signal) {
+               // gevent.signal_handler appears in gevent 1.3.
+               // On older gevent, fall back to the deprecated gevent.signal.
+               ugevent.signal = PyDict_GetItemString(gevent_dict, "signal");
+               if (!ugevent.signal) uwsgi_pyexit;
+       }
 
        ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep");
        if (!ugevent.greenlet_switch) uwsgi_pyexit;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/logsocket/logsocket_plugin.c 
new/uwsgi-2.0.19.1/plugins/logsocket/logsocket_plugin.c
--- old/uwsgi-2.0.18/plugins/logsocket/logsocket_plugin.c       2019-02-09 
15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/plugins/logsocket/logsocket_plugin.c     2020-06-17 
11:03:34.000000000 +0200
@@ -43,6 +43,7 @@
                else {
                        ul->msg.msg_iov = uwsgi_malloc(sizeof(struct iovec));
                        ul->msg.msg_iovlen = 1;
+                       ul->count = 0;
                }
 
                if (comma) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/php/php_plugin.c 
new/uwsgi-2.0.19.1/plugins/php/php_plugin.c
--- old/uwsgi-2.0.18/plugins/php/php_plugin.c   2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/plugins/php/php_plugin.c 2020-06-17 11:03:34.000000000 
+0200
@@ -1061,10 +1061,9 @@
 
        SG(request_info).path_translated = wsgi_req->file;
 
+        memset(&file_handle, 0, sizeof(zend_file_handle));
         file_handle.type = ZEND_HANDLE_FILENAME;
         file_handle.filename = real_filename;
-        file_handle.free_filename = 0;
-        file_handle.opened_path = NULL;
 
         if (php_request_startup(TSRMLS_C) == FAILURE) {
                uwsgi_500(wsgi_req);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/psgi/psgi.h 
new/uwsgi-2.0.19.1/plugins/psgi/psgi.h
--- old/uwsgi-2.0.18/plugins/psgi/psgi.h        2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/plugins/psgi/psgi.h      2020-06-17 11:03:34.000000000 
+0200
@@ -87,3 +87,5 @@
 
 void uwsgi_perl_check_auto_reload(void);
 void uwsgi_psgi_preinit_apps(void);
+
+extern struct uwsgi_perl uperl;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/psgi/psgi_loader.c 
new/uwsgi-2.0.19.1/plugins/psgi/psgi_loader.c
--- old/uwsgi-2.0.18/plugins/psgi/psgi_loader.c 2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/plugins/psgi/psgi_loader.c       2020-06-17 
11:03:34.000000000 +0200
@@ -1,7 +1,6 @@
 #include "psgi.h" 
 
 extern struct uwsgi_server uwsgi;
-struct uwsgi_perl uperl;
 
 extern struct uwsgi_plugin psgi_plugin;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/psgi/psgi_plugin.c 
new/uwsgi-2.0.19.1/plugins/psgi/psgi_plugin.c
--- old/uwsgi-2.0.18/plugins/psgi/psgi_plugin.c 2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/plugins/psgi/psgi_plugin.c       2020-06-17 
11:03:34.000000000 +0200
@@ -3,11 +3,7 @@
 extern char **environ;
 extern struct uwsgi_server uwsgi;
 
-#ifdef __APPLE__
-extern struct uwsgi_perl uperl;
-#else
 struct uwsgi_perl uperl;
-#endif
 
 struct uwsgi_plugin psgi_plugin;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/psgi/uwsgi_plmodule.c 
new/uwsgi-2.0.19.1/plugins/psgi/uwsgi_plmodule.c
--- old/uwsgi-2.0.18/plugins/psgi/uwsgi_plmodule.c      2019-02-09 
15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/plugins/psgi/uwsgi_plmodule.c    2020-06-17 
11:03:34.000000000 +0200
@@ -883,7 +883,7 @@
                XSRETURN_UNDEF;
         }
 
-       ST(0) = newSVpv(chunk, len);
+       ST(0) = newSVpvn(chunk, len);
         sv_2mortal(ST(0));
         XSRETURN(1);
 }
@@ -902,7 +902,7 @@
                 XSRETURN_UNDEF;
         }
 
-        ST(0) = newSVpv(chunk, len);
+        ST(0) = newSVpvn(chunk, len);
         sv_2mortal(ST(0));
         XSRETURN(1);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/pypy/pypy_setup.py 
new/uwsgi-2.0.19.1/plugins/pypy/pypy_setup.py
--- old/uwsgi-2.0.18/plugins/pypy/pypy_setup.py 2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/plugins/pypy/pypy_setup.py       2020-06-17 
11:03:34.000000000 +0200
@@ -326,10 +326,10 @@
     if c[0] != '/':
         c = os.getcwd() + '/' + c
     try:
-        from paste.script.util.logging_config import fileConfig
+        from logging.config import fileConfig
         fileConfig(c)
     except ImportError:
-        print "PyPy WARNING: unable to load paste.script.util.logging_config"
+        print "PyPy WARNING: unable to load logging.config"
     from paste.deploy import loadapp
     wsgi_application = loadapp('config:%s' % c)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/python/pyloader.c 
new/uwsgi-2.0.19.1/plugins/python/pyloader.c
--- old/uwsgi-2.0.18/plugins/python/pyloader.c  2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/plugins/python/pyloader.c        2020-06-17 
11:03:34.000000000 +0200
@@ -678,7 +678,7 @@
        uwsgi_log( "Loading paste environment: %s\n", paste);
 
        if (up.paste_logger) {
-               PyObject *paste_logger_dict = 
get_uwsgi_pydict("paste.script.util.logging_config");     
+               PyObject *paste_logger_dict = 
get_uwsgi_pydict("logging.config");
                if (paste_logger_dict) {
                        PyObject *paste_logger_fileConfig = 
PyDict_GetItemString(paste_logger_dict, "fileConfig");
                        if (paste_logger_fileConfig) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/python/uwsgi_pymodule.c 
new/uwsgi-2.0.19.1/plugins/python/uwsgi_pymodule.c
--- old/uwsgi-2.0.18/plugins/python/uwsgi_pymodule.c    2019-02-09 
15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/plugins/python/uwsgi_pymodule.c  2020-06-17 
11:03:34.000000000 +0200
@@ -2167,8 +2167,6 @@
                        goto clear;
                }
 
-               apps_tuple = PyDict_GetItemString(worker_dict, "apps");
-
                PyDict_Clear(worker_dict);
 
                zero = PyInt_FromLong(uwsgi.workers[i + 1].id);
@@ -2322,9 +2320,10 @@
 
                        PyTuple_SetItem(apps_tuple, j, apps_dict);
                }
-       
+
 
                PyDict_SetItemString(worker_dict, "apps", apps_tuple);
+               Py_DECREF(apps_tuple);
 
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/python/wsgi_handlers.c 
new/uwsgi-2.0.19.1/plugins/python/wsgi_handlers.c
--- old/uwsgi-2.0.18/plugins/python/wsgi_handlers.c     2019-02-09 
15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/plugins/python/wsgi_handlers.c   2020-06-17 
11:03:34.000000000 +0200
@@ -461,31 +461,32 @@
 }
 
 PyObject *py_uwsgi_sendfile(PyObject * self, PyObject * args) {
-
+       int chunk_size;
+       PyObject *filelike;
        struct wsgi_request *wsgi_req = py_current_wsgi_req();
 
-       if (!PyArg_ParseTuple(args, "O|i:uwsgi_sendfile", 
&wsgi_req->async_sendfile, &wsgi_req->sendfile_fd_chunk)) {
+       if (!PyArg_ParseTuple(args, "O|i:uwsgi_sendfile", &filelike, 
&chunk_size)) {
                return NULL;
        }
 
-#ifdef PYTHREE
-       wsgi_req->sendfile_fd = 
PyObject_AsFileDescriptor(wsgi_req->async_sendfile);
-       if (wsgi_req->sendfile_fd >= 0) {
-               Py_INCREF((PyObject *)wsgi_req->async_sendfile);
-       }
-#else
-       if (PyFile_Check((PyObject *)wsgi_req->async_sendfile)) {
-               Py_INCREF((PyObject *)wsgi_req->async_sendfile);
-               wsgi_req->sendfile_fd = 
PyObject_AsFileDescriptor(wsgi_req->async_sendfile);
+       if (!PyObject_HasAttrString(filelike, "read")) {
+               PyErr_SetString(PyExc_AttributeError, "object has no attribute 
'read'");
+               return NULL;
        }
-#endif
 
-       // PEP 333 hack
-       wsgi_req->sendfile_obj = wsgi_req->async_sendfile;
-       //wsgi_req->sendfile_obj = (void *) PyTuple_New(0);
+       // wsgi.file_wrapper called a second time? Forget the old reference.
+       if (wsgi_req->async_sendfile) {
+               Py_DECREF(wsgi_req->async_sendfile);
+       }
 
-       Py_INCREF((PyObject *) wsgi_req->sendfile_obj);
-       return (PyObject *) wsgi_req->sendfile_obj;
+       // XXX: Not 100% sure why twice.
+       //      Maybe: We keep one at async_sendfile and transfer
+       //      one to the caller (even though he gave it to us).
+       Py_INCREF(filelike);
+       Py_INCREF(filelike);
+       wsgi_req->async_sendfile = filelike;
+       wsgi_req->sendfile_fd_chunk = chunk_size;
+       return filelike;
 }
 
 void threaded_swap_ts(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/python/wsgi_subhandler.c 
new/uwsgi-2.0.19.1/plugins/python/wsgi_subhandler.c
--- old/uwsgi-2.0.18/plugins/python/wsgi_subhandler.c   2019-02-09 
15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/plugins/python/wsgi_subhandler.c 2020-06-17 
11:03:34.000000000 +0200
@@ -76,7 +76,18 @@
                return 1;
        }
        return 0;
-} 
+}
+
+/*
+ * attempt to make a fd from a file-like PyObject - returns -1 on error.
+ */
+static int uwsgi_python_try_filelike_as_fd(PyObject *filelike) {
+       int fd;
+       if ((fd = PyObject_AsFileDescriptor(filelike)) < 0) {
+               PyErr_Clear();
+       }
+       return fd;
+}
 
 /*
 this is a hack for supporting non-file object passed to wsgi.file_wrapper
@@ -253,7 +264,9 @@
                if (uwsgi_python_send_body(wsgi_req, (PyObject 
*)wsgi_req->async_result)) goto clear;
        }
 
-       if (wsgi_req->sendfile_obj == wsgi_req->async_result) {
+       // Check if wsgi.file_wrapper has been used.
+       if (wsgi_req->async_sendfile == wsgi_req->async_result) {
+               wsgi_req->sendfile_fd = 
uwsgi_python_try_filelike_as_fd((PyObject *)wsgi_req->async_sendfile);
                if (wsgi_req->sendfile_fd >= 0) {
                        UWSGI_RELEASE_GIL
                        uwsgi_response_sendfile_do(wsgi_req, 
wsgi_req->sendfile_fd, 0, 0);
@@ -299,8 +312,14 @@
                        Py_DECREF(pychunk);
                        goto clear;
                }
-       }
-       else if (wsgi_req->sendfile_obj == pychunk) {
+       } else if (wsgi_req->async_sendfile == pychunk) {
+               //
+               // XXX: It's not clear whether this can ever be sensibly reached
+               //      based on PEP 333/3333 - it would mean the iterator 
yielded
+               //      the result of wsgi.file_wrapper. However, the iterator 
should
+               //      only ever yield `bytes`...
+               //
+               wsgi_req->sendfile_fd = 
uwsgi_python_try_filelike_as_fd((PyObject *)wsgi_req->async_sendfile);
                if (wsgi_req->sendfile_fd >= 0) {
                        UWSGI_RELEASE_GIL
                        uwsgi_response_sendfile_do(wsgi_req, 
wsgi_req->sendfile_fd, 0, 0);
@@ -310,22 +329,30 @@
                else if (PyObject_HasAttrString(pychunk, "read")) {
                        uwsgi_python_consume_file_wrapper_read(wsgi_req, 
pychunk);
                }
-
                uwsgi_py_check_write_errors {
                        uwsgi_py_write_exception(wsgi_req);
                        Py_DECREF(pychunk);
                        goto clear;
                }
+       } else if (pychunk != Py_None) {
+               // The iterator returned something that we were not able to 
handle.
+               PyObject *pystr = PyObject_Repr(pychunk);
+#ifdef PYTHREE
+               const char *cstr = PyUnicode_AsUTF8(pystr);
+#else
+               const char *cstr = PyString_AsString(pystr);
+#endif
+               uwsgi_log("[ERROR] Unhandled object from iterator: %s (%p)\n", 
cstr, pychunk);
+               Py_DECREF(pystr);
        }
 
-
        Py_DECREF(pychunk);
        return UWSGI_AGAIN;
 
 clear:
-
-       if (wsgi_req->sendfile_fd != -1) {
-               Py_DECREF((PyObject *)wsgi_req->async_sendfile);
+       // Release the reference that we took in py_uwsgi_sendfile.
+       if (wsgi_req->async_sendfile != NULL) {
+               Py_DECREF((PyObject *) wsgi_req->async_sendfile);
        }
 
        if (wsgi_req->async_placeholder) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/pyuwsgi/pyuwsgi.c 
new/uwsgi-2.0.19.1/plugins/pyuwsgi/pyuwsgi.c
--- old/uwsgi-2.0.18/plugins/pyuwsgi/pyuwsgi.c  2019-02-09 15:48:07.000000000 
+0100
+++ new/uwsgi-2.0.19.1/plugins/pyuwsgi/pyuwsgi.c        2020-06-17 
11:03:34.000000000 +0200
@@ -82,7 +82,7 @@
                PyObject *py_str = PyObject_Str(item);
                PyList_Append(args_li, py_str);
 #ifdef PYTHREE
-               char *str = PyUnicode_AsUTF8(py_str);
+               const char *str = PyUnicode_AsUTF8(py_str);
                size += strlen(str) + 1;
 #else
                size += PyObject_Length(item) + 1;
@@ -102,7 +102,7 @@
        for (i = 0; i < new_argc; i++) {
                PyObject *arg = PyList_GetItem(args_li, i);
 #ifdef PYTHREE
-               char *arg_str = PyUnicode_AsUTF8(arg);
+               const char *arg_str = PyUnicode_AsUTF8(arg);
 #else
                char *arg_str = PyString_AsString(arg);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/redislog/redislog_plugin.c 
new/uwsgi-2.0.19.1/plugins/redislog/redislog_plugin.c
--- old/uwsgi-2.0.18/plugins/redislog/redislog_plugin.c 2019-02-09 
15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/plugins/redislog/redislog_plugin.c       2020-06-17 
11:03:34.000000000 +0200
@@ -159,7 +159,7 @@
                uredislog->fd = uwsgi_connect(uredislog->address, 
uwsgi.socket_timeout, 0);
                if (uredislog->password) {
                  setup_iov.iov_len = snprintf(
-                   setup_buf, sizeof (setup_buf), 
"*2\r\n$4\r\nauth\r\n$%lu\r\n%*s\r\n",
+                   setup_buf, sizeof (setup_buf), 
"*2\r\n$4\r\nauth\r\n$%zu\r\n%*s\r\n",
                    strlen(uredislog->password), 
(int)strlen(uredislog->password), uredislog->password);
                  setup_iov.iov_base = setup_buf;
                  ret = writev(uredislog->fd, &setup_iov, 1);
@@ -172,7 +172,7 @@
                }
                if (uredislog->id) {
                  setup_iov.iov_len = snprintf(
-                   setup_buf, sizeof (setup_buf), 
"*2\r\n$6\r\nselect\r\n$%lu\r\n%*s\r\n",
+                   setup_buf, sizeof (setup_buf), 
"*2\r\n$6\r\nselect\r\n$%zu\r\n%*s\r\n",
                    strlen(uredislog->id), (int)strlen(uredislog->id), 
uredislog->id);
                  setup_iov.iov_base = setup_buf;
                  ret = writev(uredislog->fd, &setup_iov, 1);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/plugins/router_static/router_static.c 
new/uwsgi-2.0.19.1/plugins/router_static/router_static.c
--- old/uwsgi-2.0.18/plugins/router_static/router_static.c      2019-02-09 
15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/plugins/router_static/router_static.c    2020-06-17 
11:03:34.000000000 +0200
@@ -239,7 +239,7 @@
         }
 
        if (wsgi_req->socket->can_offload) {
-               if (!uwsgi_offload_request_sendfile_do(wsgi_req, fd, 
st.st_size)) {
+               if (!uwsgi_offload_request_sendfile_do(wsgi_req, fd, 0, 
st.st_size)) {
                         wsgi_req->via = UWSGI_VIA_OFFLOAD;
                         wsgi_req->response_size += st.st_size;
                        // the fd will be closed by the offload engine
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/uwsgi-2.0.18/plugins/transformation_offload/offload.c 
new/uwsgi-2.0.19.1/plugins/transformation_offload/offload.c
--- old/uwsgi-2.0.18/plugins/transformation_offload/offload.c   2019-02-09 
15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/plugins/transformation_offload/offload.c 2020-06-17 
11:03:34.000000000 +0200
@@ -25,7 +25,7 @@
                struct uwsgi_transformation *orig_ut = (struct 
uwsgi_transformation *) ut->data;
                // sendfile offload
                if (orig_ut->fd > -1) {
-                       if (!uwsgi_offload_request_sendfile_do(wsgi_req, 
orig_ut->fd, orig_ut->len)) {
+                       if (!uwsgi_offload_request_sendfile_do(wsgi_req, 
orig_ut->fd, 0, orig_ut->len)) {
                                // the fd will be closed by the offload engine
                                orig_ut->fd = -1;
                                wsgi_req->via = UWSGI_VIA_OFFLOAD;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/proto/http.c 
new/uwsgi-2.0.19.1/proto/http.c
--- old/uwsgi-2.0.18/proto/http.c       2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/proto/http.c     2020-06-17 11:03:34.000000000 +0200
@@ -276,7 +276,7 @@
                 }
        }
        else {
-               char *server_port = strchr(wsgi_req->socket->name, ':');
+               char *server_port = strrchr(wsgi_req->socket->name, ':');
                if (server_port) {
                        wsgi_req->uh->pktsize += 
proto_base_add_uwsgi_var(wsgi_req, "SERVER_PORT", 11, server_port+1, 
strlen(server_port+1));
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/setup.py new/uwsgi-2.0.19.1/setup.py
--- old/uwsgi-2.0.18/setup.py   2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/setup.py 2020-06-17 11:03:34.000000000 +0200
@@ -136,5 +136,7 @@
         'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: 3.8',
     ],
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/tests/static/test.txt 
new/uwsgi-2.0.19.1/tests/static/test.txt
--- old/uwsgi-2.0.18/tests/static/test.txt      1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.19.1/tests/static/test.txt    2020-06-17 11:03:34.000000000 
+0200
@@ -0,0 +1 @@
+cookie
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/tests/static/test2.txt 
new/uwsgi-2.0.19.1/tests/static/test2.txt
--- old/uwsgi-2.0.18/tests/static/test2.txt     1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.19.1/tests/static/test2.txt   2020-06-17 11:03:34.000000000 
+0200
@@ -0,0 +1 @@
+cookie2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/tests/testfilewrapper.py 
new/uwsgi-2.0.19.1/tests/testfilewrapper.py
--- old/uwsgi-2.0.18/tests/testfilewrapper.py   1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.19.1/tests/testfilewrapper.py 2020-06-17 11:03:34.000000000 
+0200
@@ -0,0 +1,122 @@
+from __future__ import print_function
+import gc
+import io
+import os.path
+import time
+
+import flask
+import flask.helpers
+
+
+application = flask.Flask(__name__)
+
+FILENAME = os.path.join(os.path.dirname(__file__), "static", "test.txt")
+FILENAME2 = os.path.join(os.path.dirname(__file__), "static", "test2.txt")
+
[email protected]_request
+def _after(response):
+    gc.collect()
+    fds = os.listdir("/proc/self/fd")
+    print("PY: objects:", len(gc.get_objects()), "fds:", len(fds))
+    return response
+
[email protected]("/")
+def index():
+    return "HELLO\n"
+
[email protected]("/1")
+def send_file_1():
+    fp = open(FILENAME, "rb")
+    return flask.send_file(fp, attachment_filename="test.txt")
+
+
[email protected]("/2")
+def send_file_2():
+    bio = io.BytesIO(b"cookie\n")
+    return flask.send_file(bio, attachment_filename="test.txt")
+
+
[email protected]("/3")
+def send_file_3():
+    """
+    What happens if we call the wsgi.file_wrapper twice?
+
+    This should respond with cookie2
+    """
+    fp = open(FILENAME, "rb")
+    flask.send_file(fp, attachment_filename="test.txt")
+    fp = open(FILENAME2, "rb")
+    return flask.send_file(fp, attachment_filename="test.txt")
+
+
[email protected]("/4")
+def send_file_4():
+    """
+    Non-filelike object to send_file/wrap_file/wsgi.file_wrapper.
+
+    AttributeError on the call to wsgi.file_wrapper.
+    """
+    return flask.send_file(object(), attachment_filename="test.txt")
+
+
[email protected]("/stream1")
+def stream1():
+    """
+    Unrelated to wsgi.file_wrapper, just ensuring the iterator stuff still 
works.
+    """
+    def _yield():
+        start = time.time()
+        for i in range(3):
+            time.sleep(0.1)
+            yield " {:.2f} cookie".format(time.time() - start).encode("utf-8")
+        yield b"\n"
+    return flask.Response(_yield(), mimetype="text/plain")
+
+
[email protected]("/stream2")
+def stream2():
+    """
+    Yielding the result of a wrap_file call with a file object.
+
+    gunicorn / werkzeug do not support this as it's not required.
+    """
+    fp = open(FILENAME, "rb")
+    resp = flask.helpers.wrap_file(flask.request.environ, fp)
+    print("PY: resp after return", hex(id(resp)))
+
+    def _yield():
+        print("PY: _yield() run", hex(id(resp)), repr(resp))
+        yield resp
+    return flask.Response(_yield())
+
+
[email protected]("/stream3")
+def stream3():
+    """
+    Yielding the result of a wrap_file call with a BytesIO object.
+
+    gunicorn / werkzeug do not support this as it's not required.
+    """
+    bio = io.BytesIO(b"cookie\n")
+    resp = flask.helpers.wrap_file(flask.request.environ, bio)
+
+    def _yield():
+        yield resp
+    return flask.Response(_yield())
+
+
[email protected]("/stream4")
+def stream4():
+    """
+    werkzeug logs: AssertionError: applications must write bytes
+    gunicorn logs: TypeError: <Response streamed [200 OK]> is not a byte
+    uwsgi didn't log, should now..
+    """
+    fp = open(FILENAME, "rb")
+    resp = flask.send_file(fp, attachment_filename="test.txt")
+    print("PY: resp after return", hex(id(resp)))
+
+    def _yield():
+        print("PY: _yield() run", hex(id(resp)), repr(resp))
+        yield resp
+    return flask.Response(_yield(), direct_passthrough=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/tests/testrpc.py 
new/uwsgi-2.0.19.1/tests/testrpc.py
--- old/uwsgi-2.0.18/tests/testrpc.py   1970-01-01 01:00:00.000000000 +0100
+++ new/uwsgi-2.0.19.1/tests/testrpc.py 2020-06-17 11:03:34.000000000 +0200
@@ -0,0 +1,13 @@
+import uwsgi
+
+def hello():
+    pass
+
+def application(env, start_response):
+    try:
+        uwsgi.register_rpc("A"*300, hello)
+        start_response('500 Buffer Overflow', [('Content-Type', 'text/plain')])
+    except ValueError:
+        start_response('200 OK', [('Content-Type', 'text/plain')])
+
+    return ()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/tests/testworkers.py 
new/uwsgi-2.0.19.1/tests/testworkers.py
--- old/uwsgi-2.0.18/tests/testworkers.py       1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.19.1/tests/testworkers.py     2020-06-17 11:03:34.000000000 
+0200
@@ -0,0 +1,26 @@
+"""
+Regression test for #2056 - uwsgi.workers() leaking objects.
+"""
+import uwsgi
+import gc
+
+
+def application(env, start_response):
+    gc.collect()
+    start_objs = len(gc.get_objects())
+
+    for i in range(200):
+        uwsgi.workers()
+
+    gc.collect()
+    end_objs = len(gc.get_objects())
+    diff_objs = end_objs - start_objs
+
+    # Sometimes there is a spurious diff of 4 objects or so.
+    if diff_objs > 10:
+        start_response('500 Leaking', [('Content-Type', 'text/plain')])
+        yield "Leaking objects...\n".format(diff_objs).encode("utf-8")
+    else:
+        start_response('200 OK', [('Content-Type', 'text/plain')])
+
+    yield "{} {} {}\n".format(start_objs, end_objs, diff_objs).encode("utf-8")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/tests/travis.sh 
new/uwsgi-2.0.19.1/tests/travis.sh
--- old/uwsgi-2.0.18/tests/travis.sh    2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/tests/travis.sh  2020-06-17 11:03:34.000000000 +0200
@@ -1,4 +1,5 @@
 #!/bin/bash
+set -u
 
 
 txtund=$(tput sgr 0 1)          # underline
@@ -57,13 +58,13 @@
 test_python() {
     date > reload.txt
     rm -f uwsgi.log
-    echo -e "${bldyel}================== TESTING $1 
=====================${txtrst}"
+    echo -e "${bldyel}================== TESTING $1 $2 
=====================${txtrst}"
     echo -e "${bldyel}>>> Spawning uWSGI python app${txtrst}"
     echo -en "${bldred}"
-    ./uwsgi --master --plugin 0:$1 --http :8080 --exit-on-reload 
--touch-reload reload.txt --wsgi-file tests/staticfile.py --daemonize uwsgi.log
+    ./uwsgi --master --plugin 0:$1 --http :8080 --exit-on-reload 
--touch-reload reload.txt --wsgi-file $2 --daemonize uwsgi.log
     echo -en "${txtrst}"
     http_test "http://localhost:8080/";
-    echo -e "${bldyel}===================== DONE $1 
=====================${txtrst}\n\n"
+    echo -e "${bldyel}===================== DONE $1 $2 
=====================${txtrst}\n\n"
 }
 
 
@@ -71,31 +72,35 @@
     date > reload.txt
     rm -f uwsgi.log
     # the code assumes that ruby environment is activated by `rvm use`
-    echo -e "${bldyel}================== TESTING $1 
=====================${txtrst}"
+    echo -e "${bldyel}================== TESTING $1 $2 
=====================${txtrst}"
     echo -e "${bldyel}>>> Installing sinatra gem using gem${txtrst}"
     gem install sinatra || die
     echo -e "${bldyel}>>> Spawning uWSGI rack app${txtrst}"
     echo -en "${bldred}"
-    ./uwsgi --master --plugin 0:$1 --http :8080 --exit-on-reload 
--touch-reload reload.txt --rack examples/config2.ru --daemonize uwsgi.log
+    ./uwsgi --master --plugin 0:$1 --http :8080 --exit-on-reload 
--touch-reload reload.txt --rack $2 --daemonize uwsgi.log
     echo -en "${txtrst}"
     http_test "http://localhost:8080/hi";
-    echo -e "${bldyel}===================== DONE $1 
=====================${txtrst}\n\n"
+    echo -e "${bldyel}===================== DONE $1 $2 
=====================${txtrst}\n\n"
 }
 
 
 while read PV ; do
-    test_python $PV
+    for WSGI_FILE in tests/staticfile.py tests/testworkers.py tests/testrpc.py 
; do
+        test_python $PV $WSGI_FILE
+    done
 done < <(cat .travis.yml | grep "plugins/python base" | sed 
s_".*plugins/python base "_""_g)
 
 
 while read RV ; do
-    test_rack $RV
+    for RACK in examples/config2.ru ; do
+        test_rack $RV $RACK
+    done
 done < <(cat .travis.yml | grep "plugins/rack base" | sed s_".*plugins/rack 
base "_""_g)
 
 
-echo "${bldgre}>>> $SUCCESS SUCCESSFUL PLUGIN(S)${txtrst}"
+echo "${bldgre}>>> $SUCCESS SUCCESSFUL TEST(S)${txtrst}"
 if [ $ERROR -ge 1 ]; then
-    echo "${bldred}>>> $ERROR FAILED PLUGIN(S)${txtrst}"
+    echo "${bldred}>>> $ERROR FAILED TEST(S)${txtrst}"
     exit 1
 fi
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/tests/werkzeug.py 
new/uwsgi-2.0.19.1/tests/werkzeug.py
--- old/uwsgi-2.0.18/tests/werkzeug.py  2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/tests/werkzeug.py        1970-01-01 01:00:00.000000000 
+0100
@@ -1,5 +0,0 @@
-import uwsgi
-
-print(uwsgi.opt)
-print(uwsgi.magic_table)
-from werkzeug.testapp import test_app as application
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/tests/werkzeug_app.py 
new/uwsgi-2.0.19.1/tests/werkzeug_app.py
--- old/uwsgi-2.0.18/tests/werkzeug_app.py      1970-01-01 01:00:00.000000000 
+0100
+++ new/uwsgi-2.0.19.1/tests/werkzeug_app.py    2020-06-17 11:03:34.000000000 
+0200
@@ -0,0 +1,5 @@
+import uwsgi
+
+print(uwsgi.opt)
+print(uwsgi.magic_table)
+from werkzeug.testapp import test_app as application
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/uwsgi.gemspec 
new/uwsgi-2.0.19.1/uwsgi.gemspec
--- old/uwsgi-2.0.18/uwsgi.gemspec      2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/uwsgi.gemspec    2020-06-17 11:03:34.000000000 +0200
@@ -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        = '2019-02-09'
+  s.date        = '2020-06-14'
   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.18/uwsgi.h new/uwsgi-2.0.19.1/uwsgi.h
--- old/uwsgi-2.0.18/uwsgi.h    2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/uwsgi.h  2020-06-17 11:03:34.000000000 +0200
@@ -614,6 +614,8 @@
        char *chdir;
 
        int max_throttle;
+
+       int notifypid;
 };
 
 struct uwsgi_logger {
@@ -1631,6 +1633,8 @@
                struct sockaddr_in6 sin6;
                struct sockaddr_un sun;
        } client_addr;
+
+       uint8_t websocket_is_fin;
 };
 
 
@@ -2837,6 +2841,13 @@
 #ifdef UWSGI_SSL
        int tlsv1;
 #endif
+
+       // uWSGI 2.0.19
+       int emperor_graceful_shutdown;
+       int is_chrooted;
+       struct uwsgi_buffer *websockets_continuation_buffer;
+
+       uint64_t max_worker_lifetime_delta;
 };
 
 struct uwsgi_rpc {
@@ -3380,6 +3391,7 @@
 char *uwsgi_num2str(int);
 char *uwsgi_float2str(float);
 char *uwsgi_64bit2str(int64_t);
+char *uwsgi_size2str(size_t);
 
 char *magic_sub(char *, size_t, size_t *, char *[]);
 void init_magic_table(char *[]);
@@ -4405,7 +4417,7 @@
 void uwsgi_offload_engines_register_all(void);
 
 struct uwsgi_thread *uwsgi_offload_thread_start(void);
-int uwsgi_offload_request_sendfile_do(struct wsgi_request *, int, size_t);
+int uwsgi_offload_request_sendfile_do(struct wsgi_request *, int, size_t, 
size_t);
 int uwsgi_offload_request_net_do(struct wsgi_request *, char *, struct 
uwsgi_buffer *);
 int uwsgi_offload_request_memory_do(struct wsgi_request *, char *, size_t);
 int uwsgi_offload_request_pipe_do(struct wsgi_request *, int, size_t);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/uwsgi-2.0.18/uwsgiconfig.py 
new/uwsgi-2.0.19.1/uwsgiconfig.py
--- old/uwsgi-2.0.18/uwsgiconfig.py     2019-02-09 15:48:07.000000000 +0100
+++ new/uwsgi-2.0.19.1/uwsgiconfig.py   2020-06-17 11:03:34.000000000 +0200
@@ -1,6 +1,6 @@
 # uWSGI build system
 
-uwsgi_version = '2.0.18'
+uwsgi_version = '2.0.19.1'
 
 import os
 import re
@@ -27,6 +27,10 @@
 except:
     import configparser as ConfigParser
 
+try:
+    from shlex import quote
+except ImportError:
+    from pipes import quote
 
 PY3 = sys.version_info[0] == 3
 
@@ -203,11 +207,12 @@
 
 def spcall3(cmd):
     p = subprocess.Popen(cmd, shell=True, stdin=open('/dev/null'), 
stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+    (out, err) = p.communicate()
 
-    if p.wait() == 0:
+    if p.returncode == 0:
         if sys.version_info[0] > 2:
-            return p.stderr.read().rstrip().decode()
-        return p.stderr.read().rstrip()
+            return err.rstrip().decode()
+        return err.rstrip()
     else:
         return None
 
@@ -592,7 +597,7 @@
             t.join()
 
     print("*** uWSGI linking ***")
-    ldline = "%s -o %s %s %s %s" % (GCC, bin_name, ' 
'.join(uniq_warnings(ldflags)),
+    ldline = "%s -o %s %s %s %s" % (GCC, quote(bin_name), ' 
'.join(uniq_warnings(ldflags)),
         ' '.join(map(add_o, gcc_list)), ' '.join(uniq_warnings(libs)))
     print(ldline)
     ret = os.system(ldline)
_______________________________________________
openSUSE Commits mailing list -- [email protected]
To unsubscribe, email [email protected]
List Netiquette: https://en.opensuse.org/openSUSE:Mailing_list_netiquette
List Archives: 
https://lists.opensuse.org/archives/list/[email protected]

Reply via email to