php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74131 session.upload_progress doesn't work for database sessions
Submitted: 2017-02-19 21:56 UTC Modified: 2017-02-23 14:31 UTC
Votes:4
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: fred5 at originsystems dot co dot za Assigned: krakjoe (profile)
Status: Assigned Package: Session related
PHP Version: 7.0.16 OS: CentOS 7
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2017-02-19 21:56 UTC] fred5 at originsystems dot co dot za
Description:
------------
session.upload_progress always writes its $_SESSION progress information to the session.save_path session file, ignoring session_set_save_handler settings

Therefore, if a system stores session information in the database then:

1. the database session information is not updated with the progress information; and consequently
2. print_r($_SESSION) excludes any session.upload_progress information.

Rendering session.upload_progress useless for any system using database session handling.

This has become critical as PHP 7 has stopped supporting apc.rfc1867 - which is the only reliable alternative of which I am aware.

Please see http://stackoverflow.com/q/42315444/3051627 for more information on this if desired.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-02-20 10:14 UTC] laruence@php.net
-Status: Open +Status: Feedback
 [2017-02-20 10:14 UTC] laruence@php.net
I can not reproduce this, please note if you are running php via fastcgi, you should disable nginx/apache's request buffering to make this work
 [2017-02-20 11:16 UTC] fred5 at originsystems dot co dot za
-Status: Feedback +Status: Open
 [2017-02-20 11:16 UTC] fred5 at originsystems dot co dot za
thank you very much for the quick feedback!

A synopsis is as follows...

Relevant phpinfo(); configuration:
----------------------------------------------
session.save_handler	            files	files
session.save_path	            /temp/session	/temp/session
session.upload_progress.cleanup	    Off	Off
session.upload_progress.enabled	    On	On
session.upload_progress.freq	    1%	1%
session.upload_progress.min_freq    1	1
session.upload_progress.name	    PHP_SESSION_UPLOAD_PROGRESS	PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefix	    upload_progress_	upload_progress_

And our session handling code contains the following:

1. class Session implements SessionHandlerInterface {}
2. in Session::__construct() we set "session_set_save_handler($this,true);" (and the following session methods Session::open,read,write etc are defined and correctly saving and retrieving $_SESSION information from the database.

General session handling test applied:
-----------------------------------------
1. $_SESSION["test var"] = "blah blah";
This variable and value is correctly reflected serialized in the database; and
2. print $_SESSION["test var"]; prints the correct value on subsequent HTTP calls for the same session

(no session information is stored in session.save_path folder)


Specific session.upload_progress testing
-----------------------------------------

1. On our file upload page inserted: 
<input name="PHP_SESSION_UPLOAD_PROGRESS" value="ABC" id="PHP_SESSION_UPLOAD_PROGRESS" type="hidden">
(prior to our file input field)
<input name="af58aac50f2c132" id="af58aac50f2c132" type="file">

2. submit the form and trigger concurrent ajax progress call loop

The result / problem is as follows:

A. The ajax progress call contains "print_r($_SESSION);" . This returns returns only "test var" and value (as above) ie. it contains no file progress information
B. At the same time, a new session file is created in session.save_path (/temp/session) containing the following:

upload_progress_ABC|a:5:{s:10:"start_time";i:1487586588;s:14:"content_length";i:19882;s:15:"bytes_processed";i:19882;s:4:"done";b:1;s:5:"files";a:1:{i:0;a:7:{s:10:"field_name";s:15:"af58aac50f2c132";s:4:"name";s:20:"bugs.xlsx";s:8:"tmp_name";s:37:"/temp/uploads/phpCvyjWg";s:5:"error";i:0;s:4:"done";b:1;s:10:"start_time";i:1487586588;s:15:"bytes_processed";i:18795;}}}

It contains only session information relating to the upload.  (ie. the information I am expecting to be both saved in the database and reflected in $_SESSION)

I hope this explains the problem in more detail but please let me know if I can provide further information!

Regarding apache - here is more detail of our configuration:

# httpd -M
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 mpm_prefork_module (static)
 authn_file_module (shared)
 authn_core_module (shared)
 authz_host_module (shared)
 authz_groupfile_module (shared)
 authz_user_module (shared)
 authz_core_module (shared)
 auth_basic_module (shared)
 reqtimeout_module (shared)
 filter_module (shared)
 mime_module (shared)
 log_config_module (shared)
 env_module (shared)
 headers_module (shared)
 setenvif_module (shared)
 version_module (shared)
 unixd_module (shared)
 status_module (shared)
 autoindex_module (shared)
 dir_module (shared)
 alias_module (shared)
 php7_module (shared)
 expires_module (shared)
 rewrite_module (shared)
 socache_shmcb_module (shared)
 deflate_module (shared)
 ssl_module (shared)
 [2017-02-20 11:22 UTC] laruence@php.net
in that case, I understand what the problem is now. I am afraid that is no way to "fix", because php receiving upload is ahead of any user codes being executed.
 [2017-02-20 11:56 UTC] fred5 at originsystems dot co dot za
Thanks very much for the candid feedback Laurence.

We are on PHP 5.6 and currently use APCu cache with apc.rfc1867 very successfully. We have provided reliable progress bar information to our customers for some years now using this technique.

The problem for me really is as follows:

1. Your answer renders session.upload_progress useless to us (and anyone using database sessions)
See: http://stackoverflow.com/q/29867392/3051627

2. PHP 7 seems to have dropped support for apc.rfc1867 in the APCu cache.
See: http://stackoverflow.com/q/42309168/3051627

3. We support client browsers as far back as IE9, so are unable to use the new HTML5 browser capabilities
See: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications


The combination of these things effectively means that we are unable to upgrade to PHP 7 - which is critical for us!

I'll be honest; at the moment I'm feeling like PHP has abandoned us entirely by dropping support for critical features without providing a workable replacement, but I am hoping that this is a lack of knowledge on my part and that there is some tricky way of achieving a file progress bar in PHP 7 that can both:

1. support older browsers; and 
2. work with database sessions


Is there possibly any advice you can give me that will allow us to achieve the above in PHP 7? (for example is it possible that the apc.rfc1867 values could be made available again in APCu)

thanks again for your very prompt feedback.
 [2017-02-20 12:23 UTC] laruence@php.net
apcu use an internal cache to cache upload progress, php7 use session(according to session.save_handler) to cache that info;

I am not sure why you think php doesn't support rfc1867, the problem here is, when php is receiving upload progresss infos from webserver, no user codes has been executed, when php is try to store upload porgress infos into session, how do he knows that you are using database session save handler?

you can still get upload progress infos before you calling set_save_handler(which change the session.save_handler that php used to cache progress info .)
 [2017-02-20 12:56 UTC] fred5 at originsystems dot co dot za
thanks again!

Regarding:

1. I am not sure why you think php doesn't support rfc1867

In PHP 7, even with both APCu and APC Backward Compatibility (apc-bc) installed, the apc.rfc1867 keys no longer show in phpinfo, and are likewise not accessible when uploading using apc. So the upload does not work. 

Please see here for explanation of the problem: https://github.com/krakjoe/apcu-bc/issues/22

My 100% first prize at this point would be able to continue to use APC. With this in mind should I open a separate bug for getting the apc.rfc1867 keys re-instated? (they are still very much included in the PHP documentation)

2. Your suggestion regarding session.upload_progress
We have a standard handling that applies to every call made to the server. In every case, Session is set up as the first step, which means that we would need to take something like the following approach:

Within Session::__construct() {
 ...
 $fileSESSION = $_SESSION;
 session_set_save_handler($this,true);
 array_merge($_SESSION,$fileSESSION); // ensuring that fileSESSION takes value priority
 ...
It does however seem a bit of a hack and has the following drawbacks that I can think of:
- Redundant session files get created that will need to be managed; and 
- The above is redundant overhead in every call except for those during file upload
- On completion of file upload, redundant $_SESSION file upload information will be retained

The above reasons as well as the fact that we have significant investment already in APC is why I would vastly prefer to continue using APC apc.rfc1867 if at all possible.

Please do let me know what you think - thanks again.
 [2017-02-20 21:33 UTC] fred5 at originsystems dot co dot za
Hi Laurence,

It appears that the hack I've suggested below won't work as it causes a "chicken and egg" situation ie. $_SESSION is not populated until session_start() but session_set_save_handler() must be executed prior to session_start()

The above means a recode of our "progress check" ajax call as a complete anomaly for our development framework (as it would be the only component in the entire application not using our standard session handling mechanism).

The above is something we'd really like to avoid if possible so it becomes even more desirable for us to be able to utilise APCu and apc.rfc1867 as we have been doing.

I would thus really appreciate any feedback you can provide regarding whether the fact that apc.rfc1867 not working is something I can / should log a bug for in order to get resolved.

I look forward to hearing from you - thanks!
 [2017-02-21 03:48 UTC] laruence@php.net
-Assigned To: +Assigned To: krakjoe
 [2017-02-21 03:48 UTC] laruence@php.net
I am not sure what apcu's plan, I am assigning this to the author
 [2017-02-21 08:00 UTC] fred5 at originsystems dot co dot za
Hi Krakjoe,

As further background to the below: our business invested invested a lot of time and energy in building a reliable file upload progress bar, and we have good robust tested solution, with a lot of customers out there using it. 

With the introduction of PHP 5.6 there was a slight hiccup when APC became APCu and some functionality disappeared, however the apc.rfc1867 keys remained in APCu so everything was fine.

Now however in PHP 7 we have installed both apcu and apc-bc but the apc.rfc1867 keys seem to have disappeared from phpinfo(), and our progress bar functionality thus does not work.

This effectively means we are unable to upgrade from PHP 5.6 until a solution is found.

I'm not sure if this is a minor thing or a major thing from an APCu perspective and I would very much appreciate it if we could get some clarity on this, because right now we are between a rock and a hard place.

thanks so much in advance
 [2017-02-23 14:31 UTC] fred5 at originsystems dot co dot za
I would greatly appreciate it if someone could please get hold of Krakjoe and let him know about this question as we are trying to decide what to do regarding this problem (...frankly nothing except APCu providing the keys is looking pretty)
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC