]> mop.ddnsfree.com - git repositories - brisk.git/commitdiff
the comet stream was closed without the final chunk
authorMatteo Nastasi <nastasi@alternativeoutput.it>
Sun, 13 Sep 2026 10:37:55 +0000 (12:37 +0200)
committerMatteo Nastasi <nastasi@alternativeoutput.it>
Sun, 13 Sep 2026 10:37:55 +0000 (12:37 +0200)
Streaming responses declare Transfer-Encoding: chunked and the data goes out
framed by chunked_content(), but on close the zero length chunk that
terminates the response was never sent.

With apache it went unnoticed: the daemon owned the client socket and simply
closed it. nginx instead parses the response, and every stream that renews
itself (RD_ENDTIME_DELTA, 240 seconds) looked truncated to it: "upstream
prematurely closed connection while reading upstream", one error line per
connected player per cycle.

The final chunk is added in User::stream_close(), which is already the place
where the daemon writes its last bytes before closing, and only for the
transports that really are chunked: websockets are not, and keep sending
their own close frame.

Measured: with 150 players the renewal of the streams produced 150 errors;
after the fix, 30 players and 30 stream reopenings give zero errors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014M1jiEq9cHdE5SE5j6vFuE

web/Obj/user.phh

index c98de14c49b444ee10bd93d8f3fa35c3c30327db..495e61a3ed1c0ec2abd9d2c5a35878e4fd78c12a 100644 (file)
@@ -880,7 +880,23 @@ function stream_keepalive($with_ping)
 
 function stream_close()
 {
-    return ($this->rd_transp->close());
+    $clo = $this->rd_transp->close();
+
+    /* Streaming responses declare Transfer-Encoding: chunked (see
+       headers_render) and the data goes out framed by chunked_content(), but
+       the final chunk was missing on close: whoever sits in the middle sees
+       the connection drop halfway through the response. With apache it went
+       unnoticed, because the daemon owned the client socket; nginx instead
+       parses the response and logs "upstream prematurely closed connection"
+       for every stream that renews itself. */
+    if ($this->is_chunked()) {
+        if ($clo != "") {
+            $clo = sprintf("%X\r\n", mb_strlen($clo, "ASCII")).$clo."\r\n";
+        }
+        $clo .= "0\r\n\r\n";
+    }
+
+    return ($clo);
 }
 
 function stream_postclose_get($sock, $curtime)