RE: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
Hallo Arnaud, I believe that Apache does sets its headers just before sending them, so when PHP deletes all headers in Apache's hashtable this does not removes Server, Date, etc. If this is not the case for NSAPI, solution a) seems good, but also allows to remove Date by setting it before ;) That is correct, you are able to remove the headers. For removing the Date header it would be enough to just use the header_remove() without setting it before. But if somebody does this, he knows what he is doing. I want to prevent PHP from doing things that the user cannot control or understand. Sun Webserver for example is able to compress output automatically and other things. So I am not sure what happens, if you remove headers. As source code of this webserver is not yet available (Sun wants to release it soon), I do not know *when* nsapi puts entries in his internal header hash table. Maybe its in protocol_start_response(), if so everything would be ok, and I can manually cleanup the complete webserver's hash table (solution b). But nsapi_response_headers from PHP called shows, that e.g. Date and Server are set *before* the request starts. In my opinion, a call to header_remove() from PHP should only remove headers set by PHP (e.g. revert to the state, before the PHP script started). One reason for having header_handler() and send_headers() is for example that flush() does not sends headers explicitly, but lets the server send them based on what header_handler() has set. That's not correct for at least apache: php_apache_sapi_flush(void *server_context) { ... sapi_send_headers(TSRMLS_C); r-status = SG(sapi_headers).http_response_code; SG(headers_sent) = 1; if (ap_rflush(r) 0 || r-connection-aborted) { php_handle_aborted_connection(); } } The flush function just calls sapi_send_headers so it explicitely send the headers, so my approach of do not implementing a header_handler would also correctly send the headers in this case. For NSAPI it is not even possible to send headers explicitely, you can only set them in an internal hashtable of the web server. For a typical NSAPI module the workflow is the following: Any Service handler from webserver's config sets headers in the internal hash table. Before it starts to write output, it may also set the response code. All this is not sent to the client immediately. The headers and everything is sent on protocol_start_response(). After that you cannot set any headers anymore and you have to write to the output stream. The PHP module calls the webserver's protocol_start_response() in sapi_send_headers(), so even when you flush, this must be called (in the current version of output buffering there is still a bug about this, which is fixed in the new version, I think). I repaired this by also implementing flush for nsapi in my new version, which calls like apache sapi_send_headers(TSRMLS_C). This fixes a very old bug for NSAPI. So in my opinion for the server it is no difference when to set the headers (immediately after the call to header()) or shortly before starting the reponse. And this is how CGI works - and this would be enough for NSAPI, too. The only thing that would not work is explicitely removing headers like Date:, but for this use case header_handler() could only be implemented for the op SAPI_HEADER_DELETE. But with CGI this would not be possible. Uwe -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
I implemented and tested now version a), works fine! header_remove() now only removes headers set/modified by PHP. I tested the case to remove *all* headers by cleaning the server's header hash table, but this breaks server hard: Best example: Removing the Transfer-encoding: chunked header, the server inserts at the beginning of the request before PHP is executed, is not restored on protocol_start_response, but the server still sends chunked data - the browser will not understand it. Solutions c), as I told before would also be good, but then you would not see PHP's headers in get_response_headers(). And code is not much shorter or simplier. - Uwe Schindler [EMAIL PROTECTED] - http://www.php.net NSAPI SAPI developer Bremen, Germany -Original Message- From: Uwe Schindler [mailto:[EMAIL PROTECTED] Sent: Saturday, November 29, 2008 1:09 PM To: 'Arnaud Le Blanc' Cc: 'Lukas Kahwe Smith'; internals@lists.php.net; 'Christian Schmidt'; 'Alex Leigh'; 'George Wang' Subject: RE: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader() Hallo Arnaud, I believe that Apache does sets its headers just before sending them, so when PHP deletes all headers in Apache's hashtable this does not removes Server, Date, etc. If this is not the case for NSAPI, solution a) seems good, but also allows to remove Date by setting it before ;) That is correct, you are able to remove the headers. For removing the Date header it would be enough to just use the header_remove() without setting it before. But if somebody does this, he knows what he is doing. I want to prevent PHP from doing things that the user cannot control or understand. Sun Webserver for example is able to compress output automatically and other things. So I am not sure what happens, if you remove headers. As source code of this webserver is not yet available (Sun wants to release it soon), I do not know *when* nsapi puts entries in his internal header hash table. Maybe its in protocol_start_response(), if so everything would be ok, and I can manually cleanup the complete webserver's hash table (solution b). But nsapi_response_headers from PHP called shows, that e.g. Date and Server are set *before* the request starts. In my opinion, a call to header_remove() from PHP should only remove headers set by PHP (e.g. revert to the state, before the PHP script started). One reason for having header_handler() and send_headers() is for example that flush() does not sends headers explicitly, but lets the server send them based on what header_handler() has set. That's not correct for at least apache: php_apache_sapi_flush(void *server_context) { ... sapi_send_headers(TSRMLS_C); r-status = SG(sapi_headers).http_response_code; SG(headers_sent) = 1; if (ap_rflush(r) 0 || r-connection-aborted) { php_handle_aborted_connection(); } } The flush function just calls sapi_send_headers so it explicitely send the headers, so my approach of do not implementing a header_handler would also correctly send the headers in this case. For NSAPI it is not even possible to send headers explicitely, you can only set them in an internal hashtable of the web server. For a typical NSAPI module the workflow is the following: Any Service handler from webserver's config sets headers in the internal hash table. Before it starts to write output, it may also set the response code. All this is not sent to the client immediately. The headers and everything is sent on protocol_start_response(). After that you cannot set any headers anymore and you have to write to the output stream. The PHP module calls the webserver's protocol_start_response() in sapi_send_headers(), so even when you flush, this must be called (in the current version of output buffering there is still a bug about this, which is fixed in the new version, I think). I repaired this by also implementing flush for nsapi in my new version, which calls like apache sapi_send_headers(TSRMLS_C). This fixes a very old bug for NSAPI. So in my opinion for the server it is no difference when to set the headers (immediately after the call to header()) or shortly before starting the reponse. And this is how CGI works - and this would be enough for NSAPI, too. The only thing that would not work is explicitely removing headers like Date:, but for this use case header_handler() could only be implemented for the op SAPI_HEADER_DELETE. But with CGI this would not be possible. Uwe -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
On 13.11.2008, at 14:48, Arnaud Le Blanc wrote: Hi, Committed, thanks Christian :) apache2handler, apache2filter, apache, apache_hooks, cli and cgi SAPIs have been updated. The following SAPIs need to be updated in PHP_5_3 and HEAD: aolserver, continuity, litespeed, nsapi, caudium, phttpd, roxen. (I'm CC-ing known maintainers) More informations on the change can be found in the commit message: http://news.php.net/php.cvs/54228 err .. whats the status here? regards, Lukas Kahwe Smith [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
Still working on it, hadn't have enough time for it until now, I try to do it as soon as possible! - Uwe Schindler [EMAIL PROTECTED] - http://www.php.net NSAPI SAPI developer Bremen, Germany From: Lukas Kahwe Smith [mailto:[EMAIL PROTECTED] Sent: Friday, November 28, 2008 2:07 PM To: Arnaud Le Blanc Cc: Uwe Schindler; internals@lists.php.net; 'Christian Schmidt'; Alex Leigh; George Wang Subject: Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader() On 13.11.2008, at 14:48, Arnaud Le Blanc wrote: Hi, Committed, thanks Christian :) apache2handler, apache2filter, apache, apache_hooks, cli and cgi SAPIs have been updated. The following SAPIs need to be updated in PHP_5_3 and HEAD: aolserver, continuity, litespeed, nsapi, caudium, phttpd, roxen. (I'm CC-ing known maintainers) More informations on the change can be found in the commit message: http://news.php.net/php.cvs/54228 err .. whats the status here? regards, Lukas Kahwe Smith [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
Just one question here: When implementing this into NSAPI, I found the following problem: NSAPI does not directly allows to remove all headers, you can only do this step by step. So there are three possibilities to ship around this problem: a) when SAPI_HEADER_DELETE_ALL is given, in header_handler, do the following (using the sapi_header_struct given as last parameter): zend_llist_apply(sapi_headers-headers, (llist_apply_func_t) php_nsapi_remove_header TSRMLS_CC); with: static int php_nsapi_remove_header(sapi_header_struct *sapi_header TSRMLS_DC) { char *header_name, *p; nsapi_request_context *rc = (nsapi_request_context *)SG(server_context); header_name = nsapi_strdup(sapi_header-header); if (p = strchr(header_name, ':')) *p = 0; ... param_free(pblock_remove(header_name, rc-rq-srvhdrs)); nsapi_free(header_name); return ZEND_HASH_APPLY_KEEP; } This would remove all headers, set by PHP. Headers embedded by the server itself would not be deleted (e.g. Server: etc.) b) Use some hack to get rid of all headers from the server's hashtable (like apr_table_clear()). This would remove all headers and also some important headers set by the server itself (like Server:, Chunked response headers, etc). I am not sure if this would be good, in my opinion SAPI_HEADER_DELETE_ALL should only remove headers set by PHP itself! What does the other SAPI developers think, is it safe to remove apaches default headers? I am not sure and tend to say: NO! c) Completely ignore sapi_header_handler like in CGI and set the headers later in sapi_send_headers() using the given struct with zend_llist_apply(). Then I do not have to take care of adding/removing headers, I set them to Sun Webserver shortly before starting the response. Why the difference between header_handler and send_headers? Is it ok to remove header_handler (like in CGI) and simply feed all headers in send_headers? This would make life for SAPI developers easier (also maybe in Apache). What is the idea to respond after each header change? What do you think? - Uwe Schindler [EMAIL PROTECTED] - http://www.php.net NSAPI SAPI developer Bremen, Germany -Original Message- From: Lukas Kahwe Smith [mailto:[EMAIL PROTECTED] Sent: Friday, November 28, 2008 2:07 PM To: Arnaud Le Blanc Cc: Uwe Schindler; internals@lists.php.net; 'Christian Schmidt'; Alex Leigh; George Wang Subject: Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader() On 13.11.2008, at 14:48, Arnaud Le Blanc wrote: Hi, Committed, thanks Christian :) apache2handler, apache2filter, apache, apache_hooks, cli and cgi SAPIs have been updated. The following SAPIs need to be updated in PHP_5_3 and HEAD: aolserver, continuity, litespeed, nsapi, caudium, phttpd, roxen. (I'm CC-ing known maintainers) More informations on the change can be found in the commit message: http://news.php.net/php.cvs/54228 err .. whats the status here? regards, Lukas Kahwe Smith [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
Hi, On Friday 28 November 2008 18:24:38 Uwe Schindler wrote: Just one question here: When implementing this into NSAPI, I found the following problem: NSAPI does not directly allows to remove all headers, you can only do this step by step. So there are three possibilities to ship around this problem: a) when SAPI_HEADER_DELETE_ALL is given, in header_handler, do the following (using the sapi_header_struct given as last parameter): zend_llist_apply(sapi_headers-headers, (llist_apply_func_t) php_nsapi_remove_header TSRMLS_CC); with: static int php_nsapi_remove_header(sapi_header_struct *sapi_header TSRMLS_DC) { char *header_name, *p; nsapi_request_context *rc = (nsapi_request_context *)SG(server_context); header_name = nsapi_strdup(sapi_header-header); if (p = strchr(header_name, ':')) *p = 0; ... param_free(pblock_remove(header_name, rc-rq-srvhdrs)); nsapi_free(header_name); return ZEND_HASH_APPLY_KEEP; } This would remove all headers, set by PHP. Headers embedded by the server itself would not be deleted (e.g. Server: etc.) b) Use some hack to get rid of all headers from the server's hashtable (like apr_table_clear()). This would remove all headers and also some important headers set by the server itself (like Server:, Chunked response headers, etc). I am not sure if this would be good, in my opinion SAPI_HEADER_DELETE_ALL should only remove headers set by PHP itself! What does the other SAPI developers think, is it safe to remove apaches default headers? I am not sure and tend to say: NO! c) Completely ignore sapi_header_handler like in CGI and set the headers later in sapi_send_headers() using the given struct with zend_llist_apply(). Then I do not have to take care of adding/removing headers, I set them to Sun Webserver shortly before starting the response. Why the difference between header_handler and send_headers? Is it ok to remove header_handler (like in CGI) and simply feed all headers in send_headers? This would make life for SAPI developers easier (also maybe in Apache). What is the idea to respond after each header change? I believe that Apache does sets its headers just before sending them, so when PHP deletes all headers in Apache's hashtable this does not removes Server, Date, etc. If this is not the case for NSAPI, solution a) seems good, but also allows to remove Date by setting it before ;) One reason for having header_handler() and send_headers() is for example that flush() does not sends headers explicitly, but lets the server send them based on what header_handler() has set. Regards, Arnaud -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
Hi, Committed, thanks Christian :) apache2handler, apache2filter, apache, apache_hooks, cli and cgi SAPIs have been updated. The following SAPIs need to be updated in PHP_5_3 and HEAD: aolserver, continuity, litespeed, nsapi, caudium, phttpd, roxen. (I'm CC-ing known maintainers) More informations on the change can be found in the commit message: http://news.php.net/php.cvs/54228 Regards, Arnaud On Sunday 09 November 2008 22:49:47 Uwe Schindler wrote: +1 I have no problem with implementing this for NSAPI after the patch is committed to CVS, just keep me informed about this. - Uwe Schindler [EMAIL PROTECTED] - http://www.php.net NSAPI SAPI developer Bremen, Germany -Original Message- From: Arnaud LB [mailto:[EMAIL PROTECTED] On Behalf Of Arnaud Le Blanc Sent: Sunday, November 09, 2008 10:02 PM To: internals@lists.php.net Cc: Christian Schmidt Subject: Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader() On Sunday 09 November 2008 19:51:31 Christian Schmidt wrote: Stan Vassilev | FM wrote: I suggest header_remove('*') or simply header_remove() /no param/ removes all headers (including the one PHP sets by default), so we can start with a clear state. I added header_remove('Foo'). header_remove() without arguments removes all headers (though Apache still adds some headers that you cannot remove). I have tested with apache2handler and cgi. I had to change the signature of SAPI header_handler function and sapi_header_struct, so the other SAPIs should be updated for this. I am not sure how to test all these? Creating a testing environment for all those webservers seems like a huge task. I am not comfortable with the size of this patch, given my understanding of the PHP source code and my general C skills, so I am posting this patch hoping that somebody will pick it up or help me get it into shape. It looks good. The signature change is not that bad if it forces all SAPIs to be updated and ensures that PHP behaves the same way with all SAPIs. It is also possible to add something like header_delete_handler() or header_handler_ex() to sapi_module_struct if the signature change is to be avoided. Regards, Arnaud -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
Stan Vassilev | FM wrote: I suggest header_remove('*') or simply header_remove() /no param/ removes all headers (including the one PHP sets by default), so we can start with a clear state. I added header_remove('Foo'). header_remove() without arguments removes all headers (though Apache still adds some headers that you cannot remove). I have tested with apache2handler and cgi. I had to change the signature of SAPI header_handler function and sapi_header_struct, so the other SAPIs should be updated for this. I am not sure how to test all these? Creating a testing environment for all those webservers seems like a huge task. I am not comfortable with the size of this patch, given my understanding of the PHP source code and my general C skills, so I am posting this patch hoping that somebody will pick it up or help me get it into shape. Christian Index: ext/standard/basic_functions.c === RCS file: /repository/php-src/ext/standard/basic_functions.c,v retrieving revision 1.725.2.31.2.64.2.69 diff -u -8 -p -r1.725.2.31.2.64.2.69 basic_functions.c --- ext/standard/basic_functions.c 5 Nov 2008 21:35:02 - 1.725.2.31.2.64.2.69 +++ ext/standard/basic_functions.c 9 Nov 2008 18:37:09 - @@ -1687,16 +1687,21 @@ ZEND_END_ARG_INFO() static ZEND_BEGIN_ARG_INFO_EX(arginfo_header, 0, 0, 1) ZEND_ARG_INFO(0, header) ZEND_ARG_INFO(0, replace) ZEND_ARG_INFO(0, http_response_code) ZEND_END_ARG_INFO() static +ZEND_BEGIN_ARG_INFO_EX(arginfo_header_remove, 0, 0, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +static ZEND_BEGIN_ARG_INFO_EX(arginfo_setcookie, 0, 0, 1) ZEND_ARG_INFO(0, name) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, expires) ZEND_ARG_INFO(0, path) ZEND_ARG_INFO(0, domain) ZEND_ARG_INFO(0, secure) ZEND_END_ARG_INFO() @@ -3445,16 +3450,17 @@ const zend_function_entry basic_function PHP_FE(ini_restore, arginfo_ini_restore) PHP_FE(get_include_path, arginfo_get_include_path) PHP_FE(set_include_path, arginfo_set_include_path) PHP_FE(restore_include_path, arginfo_restore_include_path) PHP_FE(setcookie, arginfo_setcookie) PHP_FE(setrawcookie, arginfo_setrawcookie) PHP_FE(header, arginfo_header) + PHP_FE(header_remove, arginfo_header_remove) PHP_FE(headers_sent, arginfo_headers_sent) PHP_FE(headers_list, arginfo_headers_list) PHP_FE(connection_aborted, arginfo_connection_aborted) PHP_FE(connection_status, arginfo_connection_status) PHP_FE(ignore_user_abort, arginfo_ignore_user_abort) PHP_FE(parse_ini_file, arginfo_parse_ini_file) PHP_FE(parse_ini_string, arginfo_parse_ini_string) Index: ext/standard/head.c === RCS file: /repository/php-src/ext/standard/head.c,v retrieving revision 1.84.2.1.2.7.2.5 diff -u -8 -p -r1.84.2.1.2.7.2.5 head.c --- ext/standard/head.c 21 Oct 2008 22:08:37 - 1.84.2.1.2.7.2.5 +++ ext/standard/head.c 9 Nov 2008 18:37:09 - @@ -45,16 +45,30 @@ PHP_FUNCTION(header) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, s|bl, ctr.line, ctr.line_len, rep, ctr.response_code) == FAILURE) return; sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, ctr TSRMLS_CC); } /* }}} */ +/* {{{
RE: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
+1 I have no problem with implementing this for NSAPI after the patch is committed to CVS, just keep me informed about this. - Uwe Schindler [EMAIL PROTECTED] - http://www.php.net NSAPI SAPI developer Bremen, Germany -Original Message- From: Arnaud LB [mailto:[EMAIL PROTECTED] On Behalf Of Arnaud Le Blanc Sent: Sunday, November 09, 2008 10:02 PM To: internals@lists.php.net Cc: Christian Schmidt Subject: Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader() On Sunday 09 November 2008 19:51:31 Christian Schmidt wrote: Stan Vassilev | FM wrote: I suggest header_remove('*') or simply header_remove() /no param/ removes all headers (including the one PHP sets by default), so we can start with a clear state. I added header_remove('Foo'). header_remove() without arguments removes all headers (though Apache still adds some headers that you cannot remove). I have tested with apache2handler and cgi. I had to change the signature of SAPI header_handler function and sapi_header_struct, so the other SAPIs should be updated for this. I am not sure how to test all these? Creating a testing environment for all those webservers seems like a huge task. I am not comfortable with the size of this patch, given my understanding of the PHP source code and my general C skills, so I am posting this patch hoping that somebody will pick it up or help me get it into shape. It looks good. The signature change is not that bad if it forces all SAPIs to be updated and ensures that PHP behaves the same way with all SAPIs. It is also possible to add something like header_delete_handler() or header_handler_ex() to sapi_module_struct if the signature change is to be avoided. Regards, Arnaud -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
On Sunday 09 November 2008 19:51:31 Christian Schmidt wrote: Stan Vassilev | FM wrote: I suggest header_remove('*') or simply header_remove() /no param/ removes all headers (including the one PHP sets by default), so we can start with a clear state. I added header_remove('Foo'). header_remove() without arguments removes all headers (though Apache still adds some headers that you cannot remove). I have tested with apache2handler and cgi. I had to change the signature of SAPI header_handler function and sapi_header_struct, so the other SAPIs should be updated for this. I am not sure how to test all these? Creating a testing environment for all those webservers seems like a huge task. I am not comfortable with the size of this patch, given my understanding of the PHP source code and my general C skills, so I am posting this patch hoping that somebody will pick it up or help me get it into shape. It looks good. The signature change is not that bad if it forces all SAPIs to be updated and ensures that PHP behaves the same way with all SAPIs. It is also possible to add something like header_delete_handler() or header_handler_ex() to sapi_module_struct if the signature change is to be avoided. Regards, Arnaud -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] Allow unsetting headers previously set usingheader()
That isn't very intuitive. I would think it was a typo when reading such code and fix the header line... I'd suggest explicit header_remove(Vary); Agreed, a specific function with a clear name sounds better. Christian, can you update the patch? - thanks! johannes I suggest header_remove('*') or simply header_remove() /no param/ removes all headers (including the one PHP sets by default), so we can start with a clear state. Regards, Stan Vassilev -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php