[resend, see followup to old thread for patch to HEAD]
It's simpler to just use the ap_r* interfaces in the the handler SAPI
for 2.0, this improves network usage by allowing httpd to buffer as
necessary, and fixes a bug where ub_write is unnecessarily pmemdup'ing
the string (it could have used a transient bucket to avoid that; the
apache2filter got this right), and stops re-using an output brigade
which is now or at least will soon be a 2.0 API violation.
(this restores constant memory use for an arbitrary length response)
--- php-4.3.7/sapi/apache2handler/sapi_apache2.c.handler
+++ php-4.3.7/sapi/apache2handler/sapi_apache2.c
@@ -67,30 +67,15 @@
static int
php_apache_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
{
-
apr_bucket *bucket;
-
apr_bucket_brigade *brigade;
request_rec *r;
php_struct *ctx; -
char *copy_str;
-
if (str_length == 0) {
-
return 0;
-
}
ctx = SG(server_context);
r = ctx->r; -
brigade = ctx->brigade;
-
copy_str = apr_pmemdup( r->pool, str, str_length);
-
bucket = apr_bucket_pool_create(copy_str, str_length, r->pool, r->connection->bucket_alloc);
-
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
-
if (ap_pass_brigade(r->output_filters, brigade) != APR_SUCCESS || r->connection->aborted) {
- if (ap_rwrite(str, str_length, r) < 0) {
php_handle_aborted_connection();
}
-
/* Ensure this brigade is empty for the next usage. */
-
apr_brigade_cleanup(brigade);
return str_length; /* we always consume all the data passed to us. */
}
@@ -245,8 +230,6 @@
php_apache_sapi_flush(void *server_context)
{
php_struct *ctx; -
apr_bucket_brigade *brigade;
-
apr_bucket *bucket;
request_rec *r;
TSRMLS_FETCH();
@@ -259,20 +242,15 @@
}
r = ctx->r;
-
brigade = ctx->brigade;
sapi_send_headers(TSRMLS_C);
r->status = SG(sapi_headers).http_response_code;
SG(headers_sent) = 1; -
/* Send a flush bucket down the filter chain. */
-
bucket = apr_bucket_flush_create(r->connection->bucket_alloc);
-
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
-
if (ap_pass_brigade(r->output_filters, brigade) != APR_SUCCESS || r->connection->aborted) {
- if (ap_rflush(r) < 0 || r->connection->aborted) {
php_handle_aborted_connection();
}
- apr_brigade_cleanup(brigade);
}
static void php_apache_sapi_log_message(char *msg)
Thanks. The patch is committed to both php4 and php5.
Edin
[resend, see followup to old thread for patch to HEAD]
It's simpler to just use the ap_r* interfaces in the the handler SAPI
for 2.0, this improves network usage by allowing httpd to buffer as
necessary, and fixes a bug where ub_write is unnecessarily pmemdup'ing
the string (it could have used a transient bucket to avoid that; the
apache2filter got this right), and stops re-using an output brigade
which is now or at least will soon be a 2.0 API violation.(this restores constant memory use for an arbitrary length response)
--- php-4.3.7/sapi/apache2handler/sapi_apache2.c.handler
+++ php-4.3.7/sapi/apache2handler/sapi_apache2.c
@@ -67,30 +67,15 @@
static int
php_apache_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
{
apr_bucket *bucket;
apr_bucket_brigade *brigade;
request_rec *r;
php_struct *ctx;char *copy_str;
if (str_length == 0) {
return 0;
}
ctx = SG(server_context);
r = ctx->r;brigade = ctx->brigade;
copy_str = apr_pmemdup( r->pool, str, str_length);
bucket = apr_bucket_pool_create(copy_str, str_length, r->pool,
r->connection->bucket_alloc); -APR_BRIGADE_INSERT_TAIL(brigade, bucket);
if (ap_pass_brigade(r->output_filters, brigade) != APR_SUCCESS ||
r->connection->aborted) { + if (ap_rwrite(str, str_length, r) < 0) {
php_handle_aborted_connection();
}/* Ensure this brigade is empty for the next usage. */
apr_brigade_cleanup(brigade);
return str_length; /* we always consume all the data passed to us. */
}
@@ -245,8 +230,6 @@
php_apache_sapi_flush(void *server_context)
{
php_struct *ctx;apr_bucket_brigade *brigade;
apr_bucket *bucket;
request_rec *r;
TSRMLS_FETCH();@@ -259,20 +242,15 @@
}r = ctx->r;
brigade = ctx->brigade;
sapi_send_headers(TSRMLS_C);
r->status = SG(sapi_headers).http_response_code;
SG(headers_sent) = 1;/* Send a flush bucket down the filter chain. */
bucket = apr_bucket_flush_create(r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
if (ap_pass_brigade(r->output_filters, brigade) != APR_SUCCESS ||
r->connection->aborted) { + if (ap_rflush(r) < 0 || r->connection->aborted)
{
php_handle_aborted_connection();
}apr_brigade_cleanup(brigade);
}static void php_apache_sapi_log_message(char *msg)