Hello Markus and thank you for your comments. I feel there are 2 things to be considered with your suggestion.
1 - It doesn't matter what the server side handler is (files/user/sqlite/mm/etc), session data is not stored until you do a session_write_close(). So for a separate process to have access to the data, the session must be closed. 2 - For the main process to update the session, a session_start() is required which generates the Set-Cookie header. Sessions DO work nearly perfectly with the main process updating by opening/closing and with the helper processes reading the status and maybe updating the abort flag. It is just the superfluous Set-Cookie headers and IE being crap. Fixing php_session_send_cookie() to compare a previously saved header with the one about to be sent shouldn't have a huge impact on the majority of code and would seem to fix the problem. I've attached a patch which I hope is more or less there. I see this as an easy fix with possible a miniscule performance increase as the header won't need to be sent when it is not needed. OOI. It may be a better solution to detect duplicate headers in the sapi_add_header_ex() function. Maybe. I suspect though that the entire cookie needs to be compared (PS should contain a smart_str prev_cookie rather than char *prev_id sort of thing), but I'm not that good at the PHP's macros and without a compiler I'm guessing. I see that the v1.360 of session.c (Line 982) introduced this "issue" by not replacing the cookie. So this has been around for a while. Please add this little patch as it will mean AJAX with IE and PHP sessions will all play nicely with each other and there is no need to add additional userland code to deal with locking as PHP sessions do EXACTLY what is required. Regards, Richard Quadling. On 14/03/07, Markus Fischer <[EMAIL PROTECTED]> wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello Richard, before starting hacking the source, what do you think about using session_set_save_handler() to specify your own custom session handlers which write your session into a database and not on the file system? I think this way, once you know the session id (which you do after the first time you call session_start), you can simply update the information in the database directly on your own without calling session_start()/sesion_write_close() numerous times. Probably you need to take care about locking on your own, but with a database that shouldn't be too hard. HTH, - - Markus Richard Quadling wrote: > Hi. > > I have a webapp which uses Ajax to initiate a process on the server > which could take several minutes to complete and will go through many > steps to before the task is finished. > > In that script, I update the session to indicate the current position > of the process. > > When the user initiates the main process, another AJAX request is made > which examines the state of the main process (via the session) and > reports back to the client - keeps them interested. The user can also > abort the process and closing the browser also triggers an abort. > > All works FINE in FF. In IE, I'm getting a "Page cannot be displayed" > sort of errror (having to debug the response to see this). This SEEMS > to relate to the fact that I am closing and opening the session in the > first script as I want to keep the session file uptodate. The process > script only has 1 output and that is the final result at the end of > the script. > > I also tested this using a telnet connection to the webserver and sent > the same headers that FireFox generated (captured via FireBub) and it > bombed just before the data arrived (Lost connection). > > e.g. > > <?php > function UpdateSession($s_Progress) { > session_start(); > $_SESSION['Progress'] = $s_Progress; > session_write_close(); > } > > //Stage 1 > UpdateSession('Loading preferences'); > ... > //Stage 10 > UpdateSession('Report generated and is now available at <a href="' . > MakeWebPath(realpath($s_PDFReport)) . '">here</a>.'); > echo rawurlencode(json_encode(array('SUCCESS' => > MakeWebPath(realpath($s_PDFReport))))); > ?> > > > As a consequence, I get ... > > Set-Cookie: PHPSESSID=uWPNRja2oT0PHPDCLqUiMzXiz1b; path=/ > Set-Cookie: PHPSESSID=uWPNRja2oT0PHPDCLqUiMzXiz1b; path=/ > Set-Cookie: PHPSESSID=uWPNRja2oT0PHPDCLqUiMzXiz1b; path=/ > ... > > LOTS of times followed by a "Page cannot be displayed". If I use > Ethereal to examine the data, it is all there and is the same via IE > and FF, it is just the IE doesn't like the REALLY long header. > > I accept this is normal behaviour and IE should "deal with it", but ... > > Is there any mileage in stopping session_start from sending the same > header if it has already been sent? If the PHPSESSID is different, > then fine, send it. > > From looking at session.c and php_session.h, I think the following > changes would suffice. > > 1 - The typedef struct _php_ps_globals {} needs to include ... > > char *prev_id; > > > 2 - In PHP_GINIT_FUNCTION(ps) ... > > ps_globals->prev_id = NULL; > > > 3 - In php_session_send_cookie(TSRMLS_D), do a comparison of prev_id > and id (taking into account prev_id could be NULL) and if different, > then allow the cookie to be set and to update prev_id with the id > sent. > > > Some other issues, if other parts of the cookie are altered, then > maybe rather than just examining the ID, the entire cookie should be > remembered. > > > Assuming that the cookie would be identical, repeatedly sending it to > the client when the session is repeatedly opened is a pain and I think > can easily be fixed. > > > Thank you for your time. > > Richard Quadling. > > > -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFF+EeF1nS0RcInK9ARAv+4AJ0U9vghOlKO5rIyxh3CmYDDXOe8zwCfXPOn 3EQjSg8mMEgVQVpiLwMBja4= =+5S8 -----END PGP SIGNATURE-----
-- ----- Richard Quadling Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731 "Standing on the shoulders of some very clever giants!"
Index: php_session.h =================================================================== RCS file: /repository/php-src/ext/session/php_session.h,v retrieving revision 1.113 diff -u -r1.113 php_session.h --- php_session.h 5 Jan 2007 03:57:57 -0000 1.113 +++ php_session.h 15 Mar 2007 08:47:50 -0000 @@ -132,6 +132,10 @@ int send_cookie; int define_sid; zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ +/* RAQ : Monday, 12 March 2007 11:56 am : Declare previous ID. + Remember the previously sent cookie to suppress sending of the same cookie when opening and + closing the session repeatedly to allow other threads access to the same session file. */ + char *prev_id; } php_ps_globals; typedef php_ps_globals zend_ps_globals; Index: session.c =================================================================== RCS file: /repository/php-src/ext/session/session.c,v retrieving revision 1.466 diff -u -r1.466 session.c --- session.c 24 Feb 2007 16:25:55 -0000 1.466 +++ session.c 15 Mar 2007 08:47:50 -0000 @@ -1117,9 +1117,21 @@ smart_str_0(&ncookie); + /* RAQ : Monday, 12 March 2007 11:56 am : Prevent duplicate session cookie. + Remember the previously sent cookie to suppress sending of the same cookie when opening and + closing the session repeatedly to allow other threads access to the same session file. */ + if (0 != strcmp(PS(id), PS(prev_id))) { + /* 'replace' must be 0 here, else a previous Set-Cookie header, probably sent with setcookie() will be replaced! */ - sapi_add_header_ex(ncookie.c, ncookie.len, 0, 0 TSRMLS_CC); + sapi_add_header_ex(ncookie.c, ncookie.len, 0, 0 TSRMLS_CC); + + /* RAQ : Monday, 12 March 2007 11:56 am : Remember id. + Remember the previously sent cookie to suppress sending of the same cookie when opening and + closing the session repeatedly to allow other threads access to the same session file. */ + strcpy(PS(prev_id), PS(id), strlen(PS(id))); + + } } PHPAPI ps_module *_php_find_ps_module(char *name TSRMLS_DC) @@ -1829,6 +1841,10 @@ ps_globals->mod_data = NULL; ps_globals->session_status = php_session_none; ps_globals->http_session_vars = NULL; +/* RAQ : Monday, 12 March 2007 11:56 am : Initialize previous id. + Remember the previously sent cookie to suppress sending of the same cookie when opening and + closing the session repeatedly to allow other threads access to the same session file. */ + ps_globals->prev_id = NULL; } static PHP_MINIT_FUNCTION(session)
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php