From 1a4ecd0664889f053891e861096f2ae1bc23e6e6 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 28 Mar 2006 09:50:47 +0000 Subject: [PATCH] - fix too aggressive caching behavour of HttpResponse --- http_response_object.c | 27 +++++++++++++++------------ http_send_api.c | 20 +++++++++++++------- package2.xml | 1 + tests/HttpResponse_001.phpt | 2 +- tests/HttpResponse_003.phpt | 2 +- tests/HttpResponse_004.phpt | 15 ++++++++------- 6 files changed, 39 insertions(+), 28 deletions(-) diff --git a/http_response_object.c b/http_response_object.c index 12a9849..918647d 100644 --- a/http_response_object.c +++ b/http_response_object.c @@ -1086,21 +1086,24 @@ PHP_METHOD(HttpResponse, send) /* caching */ if (zval_is_true(GET_STATIC_PROP(cache))) { zval *cctl, *cctl_p, *etag, *etag_p, *lmod, *lmod_p; - + etag = convert_to_type_ex(IS_STRING, GET_STATIC_PROP(eTag), &etag_p); lmod = convert_to_type_ex(IS_LONG, GET_STATIC_PROP(lastModified), &lmod_p); cctl = convert_to_type_ex(IS_STRING, GET_STATIC_PROP(cacheControl), &cctl_p); - - http_cache_etag(Z_STRVAL_P(etag), Z_STRLEN_P(etag), Z_STRVAL_P(cctl), Z_STRLEN_P(cctl)); - http_cache_last_modified(Z_LVAL_P(lmod), Z_LVAL_P(lmod) ? Z_LVAL_P(lmod) : HTTP_GET_REQUEST_TIME(), Z_STRVAL_P(cctl), Z_STRLEN_P(cctl)); - + + if (Z_LVAL_P(lmod) || Z_STRLEN_P(etag)) { + http_send_cache_control(Z_STRVAL_P(cctl), Z_STRLEN_P(cctl)); + if (Z_STRLEN_P(etag)) { + http_send_etag(Z_STRVAL_P(etag), Z_STRLEN_P(etag)); + } + if (Z_LVAL_P(lmod)) { + http_send_last_modified(Z_LVAL_P(lmod)); + } + } + if (etag_p) zval_ptr_dtor(&etag_p); if (lmod_p) zval_ptr_dtor(&lmod_p); if (cctl_p) zval_ptr_dtor(&cctl_p); - - if (php_ob_handler_used("blackhole" TSRMLS_CC)) { - RETURN_TRUE; - } } /* content type */ @@ -1156,7 +1159,7 @@ PHP_METHOD(HttpResponse, send) case SEND_DATA: { zval *zdata_p, *zdata = convert_to_type_ex(IS_STRING, GET_STATIC_PROP(data), &zdata_p); - RETVAL_SUCCESS(http_send_data_ex(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata), 1)); + RETVAL_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata))); if (zdata_p) zval_ptr_dtor(&zdata_p); return; } @@ -1167,7 +1170,7 @@ PHP_METHOD(HttpResponse, send) zval *the_stream_p, *the_stream = convert_to_type_ex(IS_LONG, GET_STATIC_PROP(stream), &the_stream_p); the_stream->type = IS_RESOURCE; php_stream_from_zval(the_real_stream, &the_stream); - RETVAL_SUCCESS(http_send_stream_ex(the_real_stream, 0, 1)); + RETVAL_SUCCESS(http_send_stream(the_real_stream)); if (the_stream_p) zval_ptr_dtor(&the_stream_p); return; } @@ -1175,7 +1178,7 @@ PHP_METHOD(HttpResponse, send) default: { zval *file_p; - RETVAL_SUCCESS(http_send_file_ex(Z_STRVAL_P(convert_to_type_ex(IS_STRING, GET_STATIC_PROP(file), &file_p)), 1)); + RETVAL_SUCCESS(http_send_file(Z_STRVAL_P(convert_to_type_ex(IS_STRING, GET_STATIC_PROP(file), &file_p)))); if (file_p) zval_ptr_dtor(&file_p); return; } diff --git a/http_send_api.c b/http_send_api.c index f8bb733..82bdff0 100644 --- a/http_send_api.c +++ b/http_send_api.c @@ -238,18 +238,19 @@ PHP_HTTP_API STATUS _http_send_etag_ex(const char *etag, size_t etag_len, char * { STATUS status; char *etag_header; + size_t etag_header_len; if (!etag_len){ http_error_ex(HE_WARNING, HTTP_E_HEADER, "Attempt to send empty ETag (previous: %s)\n", HTTP_G->send.unquoted_etag); return FAILURE; } + etag_header_len = spprintf(&etag_header, 0, "ETag: \"%s\"", etag); + status = http_send_header_string_ex(etag_header, etag_header_len, 1); + /* remember */ STR_SET(HTTP_G->send.unquoted_etag, estrndup(etag, etag_len)); - etag_len = spprintf(&etag_header, 0, "ETag: \"%s\"", etag); - status = http_send_header_string_ex(etag_header, etag_len, 1); - if (sent_header) { *sent_header = etag_header; } else { @@ -299,7 +300,6 @@ PHP_HTTP_API STATUS _http_send_ex(const void *data_ptr, size_t data_size, http_s void *s = NULL; HashTable ranges; http_range_status range_status; - int cache_etag = http_interrupt_ob_etaghandler(); if (!data_ptr) { return FAILURE; @@ -408,12 +408,16 @@ PHP_HTTP_API STATUS _http_send_ex(const void *data_ptr, size_t data_size, http_s case RANGE_NO: { zend_hash_destroy(&ranges); - + /* send 304 Not Modified if etag matches - DON'T return on ETag generation failure */ - if (!no_cache && cache_etag) { + if (!no_cache && (http_interrupt_ob_etaghandler() || (HTTP_G->send.unquoted_etag != NULL))) { char *etag = NULL; - if ((etag = http_etag(data_ptr, data_size, data_mode))) { + if (HTTP_G->send.unquoted_etag) { + etag = estrdup(HTTP_G->send.unquoted_etag); + } + + if (etag || (etag = http_etag(data_ptr, data_size, data_mode))) { char *sent_header = NULL; http_send_etag_ex(etag, strlen(etag), &sent_header); @@ -421,6 +425,8 @@ PHP_HTTP_API STATUS _http_send_ex(const void *data_ptr, size_t data_size, http_s return http_exit_ex(304, sent_header, NULL, 0); } else { STR_FREE(sent_header); + /* no caching for Last-Modified if ETags really don't match */ + no_cache = http_got_server_var("HTTP_IF_NONE_MATCH"); } efree(etag); } diff --git a/package2.xml b/package2.xml index 647e072..bdc6fd1 100644 --- a/package2.xml +++ b/package2.xml @@ -49,6 +49,7 @@ HttpResponse * Fixed Bug #7192: Build against libcurl >= 7.15.2 fails * Fixed access of super globals * Fixed sending userspace streams +* Fixed too aggressive caching behavour of HttpResponse ]]> diff --git a/tests/HttpResponse_001.phpt b/tests/HttpResponse_001.phpt index 56b1913..21db458 100644 --- a/tests/HttpResponse_001.phpt +++ b/tests/HttpResponse_001.phpt @@ -15,11 +15,11 @@ HttpResponse::send(); ?> --EXPECTF-- X-Powered-By: PHP/%s -ETag: "3858f62230ac3c915f300c664312c63f" Cache-Control: public, must-revalidate, max-age=3600 Last-Modified: %s, %d %s 20%d %d:%d:%d GMT Content-Type: %s Accept-Ranges: bytes +ETag: "3858f62230ac3c915f300c664312c63f" Content-Length: 6 foobar diff --git a/tests/HttpResponse_003.phpt b/tests/HttpResponse_003.phpt index 9780dda..22f4674 100644 --- a/tests/HttpResponse_003.phpt +++ b/tests/HttpResponse_003.phpt @@ -19,11 +19,11 @@ HttpResponse::send(); ?> --EXPECTF-- X-Powered-By: PHP/%s -ETag: "%s" Cache-Control: public, must-revalidate, max-age=3600 Last-Modified: %s, %d %s 20%d %d:%d:%d GMT Content-Type: %s Accept-Ranges: bytes +ETag: "%s" Content-Encoding: gzip Vary: Accept-Encoding diff --git a/tests/HttpResponse_004.phpt b/tests/HttpResponse_004.phpt index e8a1d0f..4e6d30c 100644 --- a/tests/HttpResponse_004.phpt +++ b/tests/HttpResponse_004.phpt @@ -5,22 +5,23 @@ HttpResponse - send cached gzipped data include 'skip.inc'; checkcgi(); checkmin(5.1); -skpif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib support"); +skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib support"); ?> ---ENV-- -HTTP_ACCEPT_ENCODING=gzip -HTTP_IF_NONE_MATCH="80b285463881575891e86ba7bfecb4d0" --FILE-- --EXPECTF-- Status: 304 X-Powered-By: PHP/%s Cache-Control: public, must-revalidate, max-age=3600 -ETag: "80b285463881575891e86ba7bfecb4d0" -Content-type: %s +Last-Modified: %s +Content-Type: %s +Accept-Ranges: bytes +ETag: "900150983cd24fb0d6963f7d28e17f72" -- 2.30.2