From 0383a651ab26c1aeec8ef8503043d7483b9795c3 Mon Sep 17 00:00:00 2001
From: "Stephen R. van den Berg" <srb@cuci.nl>
Date: Mon, 1 Jul 2019 03:16:12 +0200
Subject: [PATCH] HTTP.Server.Request: Range handling fixed for uncompressed
 files.

---
 .../HTTP.pmod/Server.pmod/Request.pike        | 26 +++++++++++++++----
 src/post_modules/Shuffler/Shuffler.cmod       |  6 ++---
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/lib/modules/Protocols.pmod/HTTP.pmod/Server.pmod/Request.pike b/lib/modules/Protocols.pmod/HTTP.pmod/Server.pmod/Request.pike
index a79580c77f..df13aa2ff1 100644
--- a/lib/modules/Protocols.pmod/HTTP.pmod/Server.pmod/Request.pike
+++ b/lib/modules/Protocols.pmod/HTTP.pmod/Server.pmod/Request.pike
@@ -775,21 +775,37 @@ void response_and_finish(mapping m, function|void _log_cb)
    if (_mode & SHUFFLER) {
      Shuffler.Shuffler sfr = Shuffler.Shuffler();
      //sfr->set_backend (backend);   // FIXME to spread CPU over more cores
-     Shuffler.Shuffle sf = sfr->shuffle(my_fd, m->start, m->size);
+     // Send a limited amount only if there is no offset
+     Shuffler.Shuffle sf = sfr->shuffle(my_fd, 0,
+      !m->start && m->size > 0 ? m->size + sizeof(send_buf) : -1);
      sf->add_source(send_buf, extend_timeout);
-     sf->set_done_callback(send_close);
 
       // The caller is presumed to take care *not* to include bodies with
      // HEAD, 1xx, 204 or 304 responses.
 
      if (m->file || m->data) {
        if (arrayp(m->data)) {
-         foreach (m->data; ; mixed data)
-           sf->add_source(data, chunker);
-         sf->add_source("0\r\n\r\n");   // Trailing headers can be added here
+         void addrest() {
+           foreach (m->data; ; mixed data)
+             sf->add_source(data, chunker);
+           sf->add_source("0\r\n\r\n");   // Trailing headers can be added here
+         }
+         if (m->start)
+           sf->set_done_callback(lambda() {
+              // Special offset handling, the header has been sent already
+             // using the previous shuffle
+             sf = sfr->shuffle(my_fd, m->start, m->size);
+             addrest();
+             sf->set_done_callback(send_close);
+             sf->start();
+           });
+         else
+           addrest();
        } else
          sf->add_source(m->file || m->data, m->start, m->size);
      }
+
+     sf->set_done_callback(send_close);
      sf->start();
    } else {
      if (m->start) {
diff --git a/src/post_modules/Shuffler/Shuffler.cmod b/src/post_modules/Shuffler/Shuffler.cmod
index 5bb5c14501..d6105aa33a 100644
--- a/src/post_modules/Shuffler/Shuffler.cmod
+++ b/src/post_modules/Shuffler/Shuffler.cmod
@@ -510,14 +510,14 @@ PIKECLASS Shuffle
       t->leftovers.len -= t->skip;
       t->skip = 0;
       if (t->left >= 0) {
-        if (t->left < t->leftovers.len)
-          t->leftovers.len = t->left;
-        t->left -= t->leftovers.len;
         if (!t->left) {
           _give_back( t, amount );
           _all_done( t, 1 );
           return;
         }
+        if (t->left < t->leftovers.len)
+          t->leftovers.len = t->left;
+        t->left -= t->leftovers.len;
       }
 
       t->leftsuffix = t->leftprefix = 0;
-- 
GitLab