* sanitize ob_httpetaghandler
[m6w6/ext-http] / http.c
diff --git a/http.c b/http.c
index 677cf9dd454350c6264d48139df503048f8eaacc..452ec8f86a98fed4ea6e2e4e17c2a43fd6f69372 100644 (file)
--- a/http.c
+++ b/http.c
@@ -15,6 +15,7 @@
 
 /* $Id$ */
 
+#define _WINSOCKAPI_
 #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
 
 #ifdef HAVE_CONFIG_H
@@ -109,6 +110,7 @@ function_entry http_functions[] = {
 #ifndef ZEND_ENGINE_2
        PHP_FE(http_build_query, NULL)
 #endif
+       PHP_FE(ob_httpetaghandler, NULL)
        {NULL, NULL, NULL}
 };
 /* }}} */
@@ -439,31 +441,60 @@ PHP_FUNCTION(http_cache_etag)
                RETURN_FALSE;
        }
 
-       php_end_ob_buffers(0 TSRMLS_CC);
        http_send_header("Cache-Control: private, must-revalidate, max-age=0");
 
        if (etag_len) {
-               RETURN_SUCCESS(http_send_etag(etag, etag_len));
+               http_send_etag(etag, etag_len);
+               if (http_etag_match("HTTP_IF_NONE_MATCH", etag)) {
+                       if (SUCCESS == http_send_status(304)) {
+                               zend_bailout();
+                       } else {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not send 304 Not Modified");
+                               RETURN_FALSE;
+                       }
+               }
        }
-       
-       /* if no etag is given and we didn't already
-        * start ob_etaghandler -- start it
-        */
+
+       /* if no etag is given and we didn't already start ob_etaghandler -- start it */
        if (!HTTP_G(etag_started)) {
-               php_ob_set_internal_handler(_http_ob_etaghandler, (uint) 4096, "etag output handler", 0 TSRMLS_CC);
-               HTTP_G(etag_started) = 1;
-               RETURN_BOOL(php_start_ob_buffer_named("etag output handler", (uint) 4096, 0 TSRMLS_CC));
+               RETURN_BOOL(HTTP_G(etag_started) = (SUCCESS == http_start_ob_handler(_http_ob_etaghandler, "ob_etaghandler", 4096, 1)));
        }
+       RETURN_TRUE;
+}
+/* }}} */
 
-       if (http_etag_match("HTTP_IF_NONE_MATCH", etag)) {
-               if (SUCCESS == http_send_status(304)) {
-                       zend_bailout();
-               } else {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not send 304 Not Modified");
-                       RETURN_FALSE;
+/* {{{ proto string ob_httpetaghandler(string data, int mode)
+ *
+ * For use with ob_start(). 
+ * Note that this has to be started as first output buffer.
+ * WARNING: Don't use with http_send_*().
+ */
+PHP_FUNCTION(ob_httpetaghandler)
+{
+       char *data;
+       int data_len;
+       long mode;
+
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &data, &data_len, &mode)) {
+               RETURN_FALSE;
+       }
+
+       if (mode & PHP_OUTPUT_HANDLER_START) {
+               if (HTTP_G(etag_started)) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "ob_httpetaghandler can only be used once");
+                       RETURN_STRINGL(data, data_len, 1);
                }
+               http_send_header("Cache-Control: private, must-revalidate, max-age=0");
+               HTTP_G(etag_started) = 1;
        }
 
+    if (OG(ob_nesting_level) > 1) {
+        php_error_docref(NULL TSRMLS_CC, E_WARNING, "ob_httpetaghandler must be started prior to other output buffers");
+        RETURN_STRINGL(data, data_len, 1);
+    }
+    
+       Z_TYPE_P(return_value) = IS_STRING;
+       http_ob_etaghandler(data, data_len, &Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value), mode);
 }
 /* }}} */
 
@@ -1135,12 +1166,12 @@ PHP_RSHUTDOWN_FUNCTION(http)
 {
        HTTP_G(etag_started) = 0;
        HTTP_G(lmod) = 0;
-       
+
        if (HTTP_G(etag)) {
                efree(HTTP_G(etag));
                HTTP_G(etag) = NULL;
        }
-       
+
        if (HTTP_G(ctype)) {
                efree(HTTP_G(ctype));
                HTTP_G(ctype) = NULL;