#endif
#include "php.h"
-#ifdef ZEND_ENGINE_2
+#include "missing.h"
+
+/* broken static properties in PHP 5.0 */
+#if defined(ZEND_ENGINE_2) && !defined(WONKY)
#include "SAPI.h"
#include "php_ini.h"
-#include "ext/standard/head.h"
#include "php_http.h"
#include "php_http_api.h"
#include "php_http_send_api.h"
#include "php_http_cache_api.h"
-#include "missing.h"
-
ZEND_EXTERN_MODULE_GLOBALS(http);
-#define USE_STATIC_PROP() USE_STATIC_PROP_EX(http_response_object_ce)
-#define GET_STATIC_PROP(n) *GET_STATIC_PROP_EX(http_response_object_ce, n)
-#define SET_STATIC_PROP(n, v) SET_STATIC_PROP_EX(http_response_object_ce, n, v)
-#define SET_STATIC_PROP_STRING(n, s, d) SET_STATIC_PROP_STRING_EX(http_response_object_ce, n, s, d)
-#define SET_STATIC_PROP_STRINGL(n, s, l, d) SET_STATIC_PROP_STRINGL_EX(http_response_object_ce, n, s, l, d)
+#define GET_STATIC_PROP(n) *GET_STATIC_PROP_EX(http_response_object_ce, n)
+#define UPD_STATIC_PROP(t, n, v) UPD_STATIC_PROP_EX(http_response_object_ce, t, n, v)
+#define SET_STATIC_PROP(n, v) SET_STATIC_PROP_EX(http_response_object_ce, n, v)
#define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpResponse, method, 0, req_args)
#define HTTP_EMPTY_ARGS(method, ret_ref) HTTP_EMPTY_ARGS_EX(HttpResponse, method, ret_ref)
HTTP_ARG_VAL(etag, 0)
HTTP_END_ARGS;
+HTTP_EMPTY_ARGS(getLastModified, 0);
+HTTP_BEGIN_ARGS(setLastModified, 1)
+ HTTP_ARG_VAL(timestamp, 0)
+HTTP_END_ARGS;
+
HTTP_EMPTY_ARGS(getCache, 0);
HTTP_BEGIN_ARGS(setCache, 1)
HTTP_ARG_VAL(cache, 0)
#define http_response_object_declare_default_properties() _http_response_object_declare_default_properties(TSRMLS_C)
static inline void _http_response_object_declare_default_properties(TSRMLS_D);
+#if BROKEN_STATICS
+HashTable http_response_statics;
+#endif
+
zend_class_entry *http_response_object_ce;
zend_function_entry http_response_object_fe[] = {
HTTP_RESPONSE_ME(setETag, ZEND_ACC_PUBLIC)
HTTP_RESPONSE_ME(getETag, ZEND_ACC_PUBLIC)
+
+ HTTP_RESPONSE_ME(setLastModified, ZEND_ACC_PUBLIC)
+ HTTP_RESPONSE_ME(getLastModified, ZEND_ACC_PUBLIC)
HTTP_RESPONSE_ME(setContentDisposition, ZEND_ACC_PUBLIC)
HTTP_RESPONSE_ME(getContentDisposition, ZEND_ACC_PUBLIC)
RETURN_FALSE;
}
- USE_STATIC_PROP();
headers = GET_STATIC_PROP(headers);
if (Z_TYPE_P(headers) != IS_ARRAY) {
}
/* convert old header to an array and add new one if header exists and replace == false */
- if (replace || SUCCESS != zend_hash_find(Z_ARRVAL_P(headers), name, name_len + 1, (void **) &header)) {
+ if (replace || (SUCCESS != zend_hash_find(Z_ARRVAL_P(headers), name, name_len + 1, (void **) &header))) {
RETURN_SUCCESS(add_assoc_stringl_ex(headers, name, name_len + 1, Z_STRVAL_P(value), Z_STRLEN_P(value), 1));
} else {
convert_to_array(*header);
RETURN_FALSE;
}
- ZVAL_BOOL(GET_STATIC_PROP(cache), do_cache);
- RETURN_TRUE;
+ RETURN_SUCCESS(UPD_STATIC_PROP(bool, cache, do_cache));
}
/* }}} */
/* {{{ proto static bool HttpResponse::setGzip(bool gzip)
*
- * Enable on-thy-fly gzipping of the sent entity. NOT IMPLEMENTED YET.
+ * Enable on-thy-fly gzipping of the sent entity.
*/
PHP_METHOD(HttpResponse, setGzip)
{
RETURN_FALSE;
}
- ZVAL_BOOL(GET_STATIC_PROP(gzip), do_gzip);
- RETURN_TRUE;
+ RETURN_SUCCESS(UPD_STATIC_PROP(bool, gzip, do_gzip));
}
/* }}} */
int cc_len;
long max_age = 0;
-#define HTTP_CACHECONTROL_TEMPLATE "%s, must-revalidate, max_age=%ld"
-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &ccontrol, &cc_len, &max_age)) {
RETURN_FALSE;
}
http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Cache-Control '%s' doesn't match public, private or no-cache", ccontrol);
RETURN_FALSE;
} else {
- USE_STATIC_PROP();
- spprintf(&cctl, 0, HTTP_CACHECONTROL_TEMPLATE, ccontrol, max_age);
- SET_STATIC_PROP_STRING(cacheControl, cctl, 0);
- RETURN_TRUE;
+ spprintf(&cctl, 0, "%s, must-revalidate, max_age=%ld", ccontrol, max_age);
+ RETVAL_SUCCESS(UPD_STATIC_PROP(string, cacheControl, cctl));
+ efree(cctl);
}
}
/* }}} */
RETURN_FALSE;
}
- USE_STATIC_PROP();
- SET_STATIC_PROP_STRINGL(contentType, ctype, ctype_len, 1);
- RETURN_TRUE;
+ RETURN_SUCCESS(UPD_STATIC_PROP(string, contentType, ctype));
}
/* }}} */
}
spprintf(&cd, 0, "%s; filename=\"%s\"", send_inline ? "inline" : "attachment", file);
- USE_STATIC_PROP();
- SET_STATIC_PROP_STRING(contentDisposition, cd, 0);
- RETURN_TRUE;
+ RETVAL_SUCCESS(UPD_STATIC_PROP(string, contentDisposition, cd));
+ efree(cd);
}
/* }}} */
RETURN_FALSE;
}
- USE_STATIC_PROP();
- SET_STATIC_PROP_STRINGL(eTag, etag, etag_len, 1);
- RETURN_TRUE;
+ RETURN_SUCCESS(UPD_STATIC_PROP(string, eTag, etag));
}
/* }}} */
/* {{{ proto static string HttpResponse::getETag()
*
- * Get the previously set custom ETag.
+ * Get calculated or previously set custom ETag.
*/
PHP_METHOD(HttpResponse, getETag)
{
}
/* }}} */
-/* {{{ proto static void HttpResponse::setThrottleDelay(double seconds)
+/* {{{ proto static bool HttpResponse::setLastModified(long timestamp)
+ *
+ * Set a custom Last-Modified date.
+ */
+PHP_METHOD(HttpResponse, setLastModified)
+{
+ long lm;
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &lm)) {
+ RETURN_FALSE;
+ }
+
+ RETURN_SUCCESS(UPD_STATIC_PROP(long, lastModified, lm));
+}
+/* }}} */
+
+/* {{{ proto static HttpResponse::getLastModified()
+ *
+ * Get calculated or previously set custom Last-Modified date.
+ */
+PHP_METHOD(HttpResponse, getLastModified)
+{
+ NO_ARGS;
+
+ IF_RETVAL_USED {
+ RETURN_LONG(Z_LVAL_P(GET_STATIC_PROP(lastModified)));
+ }
+}
+/* }}} */
+
+/* {{{ proto static bool HttpResponse::setThrottleDelay(double seconds)
*
*/
PHP_METHOD(HttpResponse, setThrottleDelay)
{
double seconds;
- if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &seconds)) {
- ZVAL_DOUBLE(GET_STATIC_PROP(throttleDelay), seconds);
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &seconds)) {
+ RETURN_FALSE;
}
+ RETURN_SUCCESS(UPD_STATIC_PROP(double, throttleDelay, seconds));
}
/* }}} */
}
/* }}} */
-/* {{{ proto static void HttpResponse::setBufferSize(long bytes)
+/* {{{ proto static bool HttpResponse::setBufferSize(long bytes)
*
*/
PHP_METHOD(HttpResponse, setBufferSize)
{
long bytes;
- if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &bytes)) {
- ZVAL_LONG(GET_STATIC_PROP(bufferSize), bytes);
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &bytes)) {
+ RETURN_FALSE;
}
+ RETURN_SUCCESS(UPD_STATIC_PROP(long, bufferSize, bytes));
}
/* }}} */
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &the_data)) {
RETURN_FALSE;
}
- convert_to_string_ex(&the_data);
+ if (Z_TYPE_P(the_data) != IS_STRING) {
+ convert_to_string_ex(&the_data);
+ }
- USE_STATIC_PROP();
- SET_STATIC_PROP(data, the_data);
- ZVAL_LONG(GET_STATIC_PROP(lastModified), http_last_modified(the_data, SEND_DATA));
- ZVAL_LONG(GET_STATIC_PROP(mode), SEND_DATA);
+ if ( (SUCCESS != SET_STATIC_PROP(data, the_data)) ||
+ (SUCCESS != UPD_STATIC_PROP(long, mode, SEND_DATA))) {
+ RETURN_FALSE;
+ }
+
+ if (!(Z_LVAL_P(GET_STATIC_PROP(lastModified)) > 0)) {
+ UPD_STATIC_PROP(long, lastModified, http_last_modified(the_data, SEND_DATA));
+ }
if (!Z_STRLEN_P(GET_STATIC_PROP(eTag))) {
- SET_STATIC_PROP_STRING(eTag, http_etag(Z_STRVAL_P(the_data), Z_STRLEN_P(the_data), SEND_DATA), 0);
+ char *etag = http_etag(Z_STRVAL_P(the_data), Z_STRLEN_P(the_data), SEND_DATA);
+ UPD_STATIC_PROP(string, eTag, etag);
+ efree(etag);
}
RETURN_TRUE;
zend_list_addref(Z_LVAL_P(the_stream));
php_stream_from_zval(the_real_stream, &the_stream);
- USE_STATIC_PROP();
- ZVAL_LONG(GET_STATIC_PROP(stream), Z_LVAL_P(the_stream));
- ZVAL_LONG(GET_STATIC_PROP(lastModified), http_last_modified(the_real_stream, SEND_RSRC));
- ZVAL_LONG(GET_STATIC_PROP(mode), SEND_RSRC);
+ if ( (SUCCESS != UPD_STATIC_PROP(long, stream, Z_LVAL_P(the_stream))) ||
+ (SUCCESS != UPD_STATIC_PROP(long, mode, SEND_RSRC))) {
+ RETURN_FALSE;
+ }
+
+ if (!(Z_LVAL_P(GET_STATIC_PROP(lastModified)) > 0)) {
+ UPD_STATIC_PROP(long, lastModified, http_last_modified(the_real_stream, SEND_RSRC));
+ }
if (!Z_STRLEN_P(GET_STATIC_PROP(eTag))) {
- SET_STATIC_PROP_STRING(eTag, http_etag(the_real_stream, 0, SEND_RSRC), 0);
+ char *etag = http_etag(the_real_stream, 0, SEND_RSRC);
+ UPD_STATIC_PROP(string, eTag, etag);
+ efree(etag);
}
RETURN_TRUE;
*/
PHP_METHOD(HttpResponse, setFile)
{
- zval *the_file;
+ char *the_file;
+ int file_len;
- if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &the_file)) {
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &the_file, &file_len)) {
+ RETURN_FALSE;
+ }
+
+ if ( (SUCCESS != UPD_STATIC_PROP(string, file, the_file)) ||
+ (SUCCESS != UPD_STATIC_PROP(long, mode, -1))) {
RETURN_FALSE;
}
- convert_to_string_ex(&the_file);
- USE_STATIC_PROP();
- SET_STATIC_PROP(file, the_file);
- ZVAL_LONG(GET_STATIC_PROP(lastModified), http_last_modified(the_file, -1));
- ZVAL_LONG(GET_STATIC_PROP(mode), -1);
+ if (!(Z_LVAL_P(GET_STATIC_PROP(lastModified)))) {
+ UPD_STATIC_PROP(long, lastModified, http_last_modified(the_file, -1));
+ }
if (!Z_STRLEN_P(GET_STATIC_PROP(eTag))) {
- SET_STATIC_PROP_STRING(eTag, http_etag(the_file, 0, -1), 0);
+ char *etag = http_etag(the_file, 0, -1);
+ UPD_STATIC_PROP(string, eTag, etag);
+ efree(etag);
}
RETURN_TRUE;
}
/* capture mode */
- if (Z_LVAL_P(GET_STATIC_PROP(catch))) {
+ if (Z_BVAL_P(GET_STATIC_PROP(catch))) {
zval the_data;
INIT_PZVAL(&the_data);
php_ob_get_buffer(&the_data TSRMLS_CC);
-
- USE_STATIC_PROP();
SET_STATIC_PROP(data, &the_data);
ZVAL_LONG(GET_STATIC_PROP(mode), SEND_DATA);
if (!Z_STRLEN_P(GET_STATIC_PROP(eTag))) {
- SET_STATIC_PROP_STRING(eTag, http_etag(Z_STRVAL(the_data), Z_STRLEN(the_data), SEND_DATA), 0);
+ char *etag = http_etag(Z_STRVAL(the_data), Z_STRLEN(the_data), SEND_DATA);
+ UPD_STATIC_PROP(string, eTag, etag);
+ efree(etag);
}
zval_dtor(&the_data);
zval **data;
FOREACH_VAL(*value, data) {
- http_send_header_ex(name, strlen(name), Z_STRVAL_PP(data), Z_STRLEN_PP(data), first);
+ http_send_header_ex(name, strlen(name), Z_STRVAL_PP(data), Z_STRLEN_PP(data), first, NULL);
first = 0;
}
} else {
- http_send_header_ex(name, strlen(name), Z_STRVAL_PP(value), Z_STRLEN_PP(value), 1);
+ http_send_header_ex(name, strlen(name), Z_STRVAL_PP(value), Z_STRLEN_PP(value), 1, NULL);
}
name = NULL;
}
/* gzip */
if (Z_LVAL_P(GET_STATIC_PROP(gzip))) {
- php_start_ob_buffer_named("ob_gzhandler", 0, 1 TSRMLS_CC);
+ php_start_ob_buffer_named("ob_gzhandler", 0, 0 TSRMLS_CC);
} else {
php_start_ob_buffer(NULL, 0, 0 TSRMLS_CC);
}
{
zval *cd = GET_STATIC_PROP(contentDisposition);
if (Z_STRLEN_P(cd)) {
- http_send_header_ex("Content-Disposition", lenof("Content-Disposition"), Z_STRVAL_P(cd), Z_STRLEN_P(cd), 1);
+ http_send_header_ex("Content-Disposition", lenof("Content-Disposition"), Z_STRVAL_P(cd), Z_STRLEN_P(cd), 1, NULL);
}
}
case SEND_DATA:
{
zval *zdata = GET_STATIC_PROP(data);
- RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)));
+ RETURN_SUCCESS(http_send_data_ex(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata), 1));
}
case SEND_RSRC:
zval *the_stream = GET_STATIC_PROP(stream);
the_stream->type = IS_RESOURCE;
php_stream_from_zval(the_real_stream, &the_stream);
- RETURN_SUCCESS(http_send_stream(the_real_stream));
+ RETURN_SUCCESS(http_send_stream_ex(the_real_stream, 0, 1));
}
default:
{
- RETURN_SUCCESS(http_send_file(Z_STRVAL_P(GET_STATIC_PROP(file))));
+ RETURN_SUCCESS(http_send_file_ex(Z_STRVAL_P(GET_STATIC_PROP(file)), 1));
}
}
}
* HttpResponse::setCache(true);
* HttpResponse::capture();
* // script follows
+ * // note that you need to call
+ * HttpResponse::send();
+ * // at the end of the script unless
+ * // you use PHP-5.1 or greater
* ?>
* </pre>
*/
INIT_PZVAL(&do_catch);
ZVAL_LONG(&do_catch, 1);
- USE_STATIC_PROP();
+
SET_STATIC_PROP(catch, &do_catch);
php_end_ob_buffers(0 TSRMLS_CC);
php_start_ob_buffer(NULL, 0, 0 TSRMLS_CC);
- /* register shutdown function */
+#if (PHP_MAJOR_VERSION > 5) || (PHP_MINOR_VERSION > 0)
+ /* register shutdown function --
+ messing around with ob and headers only works in PHP-5.1 or greater */
{
zval func, retval, arg, *argp[1];
call_user_function(EG(function_table), NULL, &func, &retval, 1, argp TSRMLS_CC);
zval_dtor(&arg);
}
+#endif
}
/* }}} */