php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48725 Support for flushing in zlib stream
Submitted: 2009-06-29 20:03 UTC Modified: 2020-08-19 10:47 UTC
Votes:25
Avg. Score:4.8 ± 0.6
Reproduced:21 of 21 (100.0%)
Same Version:3 (14.3%)
Same OS:7 (33.3%)
From: slusarz at curecanti dot org Assigned: cmb (profile)
Status: Closed Package: Streams related
PHP Version: 5.2.10 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: slusarz at curecanti dot org
New email:
PHP Version: OS:

 

 [2009-06-29 20:03 UTC] slusarz at curecanti dot org
Description:
------------
There does not seem to be any support for flushing data in a zlib compression stream.  Not sure if this is an omission, something obvious that I am missing (and may not be in the documentation), or the fact that the zlib stream filter does not support socket operation.

Reproduce code:
---------------
$stream = stream_socket_client([...]);

// Login to remote server & enable compression remotely (e.g. implementation of IMAP COMPRESS extension - RFC 4978)

stream_filter_append($stream, 'zlib.deflate', STREAM_FILTER_WRITE);
stream_set_write_buffer($stream, 0);
fwrite($stream, 'Testing');
fflush($stream);

// tcpdump confirms that nothing is sent from the PHP server to the remote server.  Can confirm that upon socket timeout, the pending data is sent.

// Similarly, compressed data from incoming stream is not available either.
stream_filter_append($stream, 'zlib.inflate', STREAM_FILTER_READ);
$in = fread($stream, 8192);

// fread() on $stream will timeout.


Patches

zlib-filter-flush-fix.patch (last revision 2012-11-02 17:15 UTC by nastasi at alternativeoutput dot it)

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-07-14 03:10 UTC] slusarz at curecanti dot org
<?php

// 16,000 bytes
$text = str_repeat('0123456789abcdef', 1000);

$temp = fopen('php://temp', 'r+');
stream_filter_append($temp, 'zlib.deflate', STREAM_FILTER_WRITE);
fwrite($temp, $text);

rewind($temp);
fpassthru($temp);

print "Location: " . ftell($temp) . "\n";

fclose($temp);

// Expected: compressed data; Location = some non-zero integer
// Actual: No data output; Location = 0
 [2009-10-19 15:15 UTC] jani@php.net
See also bug #49816
 [2009-10-22 21:40 UTC] slusarz at curecanti dot org
I don't think this is related to bug #49816.  Turning off zlib output compression (by adding "ini_set('zlib.output_compression', 'Off');" to the top of the test script)doesn't alter the results from the test script previously reported.
 [2009-10-23 12:25 UTC] jani@php.net
It's related, not same. :)
 [2011-12-13 22:36 UTC] dtrebbien at gmail dot com
See also: http://stackoverflow.com/questions/7508762/using-zlib-filter-with-a-socket-pair/
 [2012-05-20 01:45 UTC] lello-3 at hotmail dot com
Please fix this
 [2012-10-24 13:27 UTC] arnout dot boks at moxio dot com
Verified this with PHP 5.4.7 on Windows.

Another reproduce case:
-----------------------
<?php
$stream = fopen('data://text/plain;base64,' . base64_encode('Foo bar baz'), 
'r');
stream_filter_append($stream, 'zlib.deflate', STREAM_FILTER_READ);
print bin2hex(stream_get_contents($stream));

Expected:
---------
73cbcf57484a2c02e22a00     // == bin2hex(gzdeflate('Foo bar baz'))

Actual:
-------
                           // (empty)

Variations tried:
-----------------
- Replacing the 'zlib.deflate'-filter by another stream filter ('string.rot13') 
gives the correct output.
- Replacing the 'data://'-URL by a 'file://'- or 'http://'-URL pointing to the 
same data gives the correct output.
- Replacing the 'data://'-URL by a 'php://memory' or 'php://temp' stream to 
which the data has been written (and the stream rewinded) gives empty output
 [2012-11-02 17:13 UTC] nastasi at alternativeoutput dot it
I had worked on the php source code and found a fix.

To understand what happens I had traced what happens during a  

    ....
    for ($i = 0 ; $i < 3 ; $i++) {
        fwrite($s[0]);
        fread($s[1]);
        fflush($s[0]);
        fread($s[1]);
        }

loop and I found that the `deflate` function is never called with the `Z_SYNC_FLUSH` flag set because no new data are present into the `backets_in` brigade.  
My fix is to manage the `PSFS_FLAG_FLUSH_INC` case `AND` no iterations are performed on deflate function extending the 

    if (flags & PSFS_FLAG_FLUSH_CLOSE) {

managing `FLUSH_INC` too:

    if (flags & PSFS_FLAG_FLUSH_CLOSE || (flags & PSFS_FLAG_FLUSH_INC && to_be_flushed)) {

All my work is performed on Debian squeeze 6.0.5, and PHP 5.3.3-7+squeeze14 but I already check the current git version and it seems not changed for the essetial parts.
 [2020-08-19 10:47 UTC] cmb@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: cmb
 [2020-08-19 10:47 UTC] cmb@php.net
The reproducer provided by @arnout doesn't seem to be related,
since it apparently has the same root cause as bug #77069.
 [2020-08-19 16:30 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #48725: Support for flushing in zlib stream
On GitHub:  https://github.com/php/php-src/pull/6019
Patch:      https://github.com/php/php-src/pull/6019.patch
 [2020-12-08 11:25 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=20e75329f2adb11dd231852c061926d0e4080929
Log: Fix #48725: Support for flushing in zlib stream
 [2020-12-08 11:25 UTC] cmb@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 03 17:01:29 2024 UTC