|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2002-05-08 10:36 UTC] pmoor at netpeople dot ch
using phpmyadmin with apache 2.0.35 and php4.3-dev results in pages not being reloaded, when once requested. if i drop an entry in an mysql table, and re-list the table, the old entry is still showing up (the browser is displaying the old page instead of a reloaded one). this is, because apache sends a 304 nod modified header. verified with mozilla-latest-1.0.0. it worked great with apache 1.3.24 though... PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 22 23:00:01 2025 UTC |
I'd like to post a workaround without patching apache or PHP.... Just edit your script(s) to send a 'header("Last-Modified: Mon, 26 Jul 1997 05:00:00 GMT");' or just some other date older than the mdate of your script file. This solves the problem. Reason: The bug causes Apache2 to look for the mdate of the .php file to determine if it has been modified. If the browser first gets a header like above, it next time asks for the page with an 'If-Modified-Since: Mon, 26 Jul 1997 05:00:00 GMT'. Then, the httpd looks at the mdate of your script, which is always newer and says: Yes, it has been modified, "200 OK". The script will be served and it will response again with the header line from above. Round and round the story goes. :)) Greets, and have fun! DanielThis is still not fixed... PHP code needs modifying. I have tried PHP 4.2.3 and 4.3.0-pre1 with Apache 2.0.43 running on RedHat 6.2, and it still returns erroneous 304s. The following is what I 'borrowed' from the Apache's mod_include.c, which seems working within PHP 4.2.3. --- sapi/apache2filter/sapi_apache2.c~ Fri Aug 16 07:27:03 2002 +++ sapi/apache2filter/sapi_apache2.c Mon Oct 14 23:27:26 2002 @@ -558,14 +558,24 @@ return OK; } +static int includes_setup(ap_filter_t *f) +{ + /* We will ALWAYS set the no_local_copy value to 1 so + * that we will not send 304s. + */ + f->r->no_local_copy = 1; + + return OK; +} + static void php_register_hook(apr_pool_t *p) { ap_hook_pre_config(php_pre_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(php_apache_server_startup, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_insert_filter(php_insert_filter, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_read_request(php_post_read_request, NULL, NULL, APR_HOOK_MIDDLE); - ap_register_output_filter("PHP", php_output_filter, NULL, AP_FTYPE_RESOURCE); - ap_register_input_filter("PHP", php_input_filter, NULL, AP_FTYPE_RESOURCE); + ap_register_output_filter("PHP", php_output_filter, includes_setup, AP_FTYPE_RESOURCE); + ap_register_input_filter("PHP", php_input_filter, includes_setup, AP_FTYPE_RESOURCE); } AP_MODULE_DECLARE_DATA module php4_module = {This bug is _NOT_ fixed in 4.3.0 rc3! In 4.3.0, the apache2 support should not be experimental anymore, so I think, this is a real showstopper IMHO. I think, it's time to fix this issue now, it's so annoying and unneccessary. If this patch has any known drawbacks that I'm not aware of, then it's NOT the correct solution to simply ignore this subject as whole. Daniel Here is the patch again as diff against php 4.3.0 rc 3: --- sapi/apache2filter/sapi_apache2.c.old Thu Dec 12 21:48:58 2002 +++ sapi/apache2filter/sapi_apache2.c Thu Dec 12 21:50:43 2002 @@ -619,14 +619,24 @@ return OK; } +static int includes_setup(ap_filter_t *f) +{ + /* We will ALWAYS set the no_local_copy value to 1 so + * that we will not send 304s. + */ + f->r->no_local_copy = 1; + + return OK; +} + static void php_register_hook(apr_pool_t *p) { ap_hook_pre_config(php_pre_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(php_apache_server_startup, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_insert_filter(php_insert_filter, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_read_request(php_post_read_request, NULL, NULL, APR_HOOK_MIDDLE); - ap_register_output_filter("PHP", php_output_filter, NULL, AP_FTYPE_RESOURCE); - ap_register_input_filter("PHP", php_input_filter, NULL, AP_FTYPE_RESOURCE); + ap_register_output_filter("PHP", php_output_filter, includes_setup, AP_FTYPE_RESOURCE); + ap_register_input_filter("PHP", php_input_filter, includes_setup, AP_FTYPE_RESOURCE); } AP_MODULE_DECLARE_DATA module php4_module = {As another possible temporary workaround, I tried adding the directive RequestHeader unset If-Modified-Since into my Apache configuration when processing PHP scripts. This removes the If-Modified-Since header entirely, causing Apache to always return a 200 response. The resulting configuration looks like: <Files *.php> SetOutputFilter PHP SetInputFilter PHP LimitRequestBody 524288 RequestHeader unset If-Modified-Since </Files> Anyone know of a reason why this might be bad or otherwise won't work? PmAll, IIS responds the same way. I think this is more a case of reading the "manual" (w3c http spec). The reason apache "worked" before was that there was probably a bug in apache that sent the content when it was supposed to send a 304 only. When you do a browser refresh, you are sending a "If-None-Match: [etag]" header, if an etag was originally sent with the content, which it probably wasn't. You also send a "If-modified-since: [GMT HTTP DATE]" with a refresh. If the file date hasn't changed, and is within the expires time originally sent (usually a default is sent), the page won't "actually" refresh. This problem lies with the improper use (or lack thereof) of cache control headers. Try sending an etag with all of your content, and no expires header. For production make sure you send an Expires header: ) This Etag will change, if you set it based on the content, and inspire IE to refresh the page. It seems to go in http 1.0, then http 1.1 order, with IE, so if you want it to really work, make sure you aren't sending an expires header. Send an Etag only from your development server. Clearing your cache works because it forces the server to send the content. It doesn't have the option of sending a 304 if you don't send an If-none-match, or If-modified-since headers, neither of which is possible if you have deleted the data and content from your box: ) An often misunderstood aspect of intentionally sending 304s is that Apache is actually "dumb" in this respect. If you are not using php's output buffer, it is impossible to stop the content from going out. You should really use a callback function and set it in ob_start("function name"). When sending a 304 return null out of your function and the 304 will be sent, but not the content. Apache happily sends out the content with your 304 header otherwise. Using a call back function gives you a lot more control of the flow of bytes out of your server. Not doing this wastes bandwidth and server connection resources, especially considering that connection taken while the 14.4 modem user downloads your 40k page. If you capture the output and stop it, you only send the 304 and the connection is freed up. It is a lot faster to send, say, a 250 byte header than the entire page. This frees up the connection resource much faster and enables your server to scale more efficiently. It would be nice if the php team made php do this 304 header/output stuff automatically. I can help if you need it: ) it will save your users some head scratching if you add this feature. It took me an hour or two to figure out what was really happening and coded it. wget -S is your friend, use it! l8, neil