etag test & fixes; set default etag mode for temp streams to crc32(b)
authorMichael Wallner <mike@php.net>
Mon, 23 Jan 2012 16:36:58 +0000 (16:36 +0000)
committerMichael Wallner <mike@php.net>
Mon, 23 Jan 2012 16:36:58 +0000 (16:36 +0000)
php_http.c
php_http_env_response.c
php_http_etag.c
php_http_message_body.c
phpunit/MessageBodyTest.php
tests/etag001.phpt [new file with mode: 0644]

index 36f2caa42b6a05dc9948939ff921430d6f53daa3..889cb09a46d1310f1e0c34ab33d36e6103da49f2 100644 (file)
@@ -118,7 +118,7 @@ zend_php_http_globals *php_http_globals(void)
 #endif
 #endif
 PHP_INI_BEGIN()
-       PHP_HTTP_INI_ENTRY("http.etag.mode", "md5", PHP_INI_ALL, OnUpdateString, env.etag_mode)
+       PHP_HTTP_INI_ENTRY("http.etag.mode", "crc32b", PHP_INI_ALL, OnUpdateString, env.etag_mode)
        PHP_HTTP_INI_ENTRY("http.request_datashare.cookie", "0", PHP_INI_SYSTEM, OnUpdateBool, request_datashare.cookie)
        PHP_HTTP_INI_ENTRY("http.request_datashare.dns", "1", PHP_INI_SYSTEM, OnUpdateBool, request_datashare.dns)
        PHP_HTTP_INI_ENTRY("http.request_datashare.ssl", "0", PHP_INI_SYSTEM, OnUpdateBool, request_datashare.ssl)
index 2ddcb7105fc1ed73776ae494bf5637698b695fe0..0d220d0c281a1e6c193de631f96ccf38967724dd 100644 (file)
@@ -77,7 +77,7 @@ static zval *get_option(zval *options, const char *name_str, size_t name_len TSR
 
 PHP_HTTP_API php_http_cache_status_t php_http_env_is_response_cached_by_etag(zval *options, const char *header_str, size_t header_len TSRMLS_DC)
 {
-       int ret, free_etag = 0;
+       int ret = 0, free_etag = 0;
        char *header, *etag;
        zval *zetag, *zbody = NULL;
 
@@ -101,8 +101,7 @@ PHP_HTTP_API php_http_cache_status_t php_http_env_is_response_cached_by_etag(zva
 
        if (zetag && Z_STRLEN_P(zetag)) {
                etag = Z_STRVAL_P(zetag);
-       } else {
-               etag = php_http_message_body_etag(((php_http_message_body_object_t *) zend_object_store_get_object(zbody TSRMLS_CC))->body);
+       } else if ((etag = php_http_message_body_etag(((php_http_message_body_object_t *) zend_object_store_get_object(zbody TSRMLS_CC))->body))) {
                set_option(options, ZEND_STRL("etag"), IS_STRING, etag, strlen(etag) TSRMLS_CC);
                free_etag = 1;
        }
@@ -115,7 +114,9 @@ PHP_HTTP_API php_http_cache_status_t php_http_env_is_response_cached_by_etag(zva
                zval_ptr_dtor(&zetag);
        }
 
-       ret = php_http_match(header, etag, PHP_HTTP_MATCH_WORD);
+       if (etag) {
+               ret = php_http_match(header, etag, PHP_HTTP_MATCH_WORD);
+       }
 
        if (free_etag) {
                efree(etag);
index 891717d0bf8a6e46573f83a262b1bcd2beafca44..3a69756b70f53259e6fd5cd2709ca498010a3456 100644 (file)
@@ -25,15 +25,7 @@ PHP_HTTP_API php_http_etag_t *php_http_etag_init(const char *mode TSRMLS_DC)
        void *ctx;
        php_http_etag_t *e;
 
-#ifdef PHP_HTTP_HAVE_HASH
-       const php_hash_ops *eho = NULL;
-
-       if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) {
-               ctx = emalloc(eho->context_size);
-               eho->hash_init(ctx);
-       } else
-#endif
-       if (mode && ((!strcasecmp(mode, "crc32")) || (!strcasecmp(mode, "crc32b")))) {
+       if (mode && (!strcasecmp(mode, "crc32b"))) {
                ctx = emalloc(sizeof(uint));
                *((uint *) ctx) = ~0;
        } else if (mode && !strcasecmp(mode, "sha1")) {
@@ -41,6 +33,14 @@ PHP_HTTP_API php_http_etag_t *php_http_etag_init(const char *mode TSRMLS_DC)
        } else if (mode && !strcasecmp(mode, "md5")) {
                PHP_MD5Init(ctx = emalloc(sizeof(PHP_MD5_CTX)));
        } else {
+#ifdef PHP_HTTP_HAVE_HASH
+               const php_hash_ops *eho = NULL;
+
+               if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) {
+                       ctx = emalloc(eho->context_size);
+                       eho->hash_init(ctx);
+               } else
+#endif
                return NULL;
        }
 
@@ -57,24 +57,32 @@ PHP_HTTP_API char *php_http_etag_finish(php_http_etag_t *e)
        unsigned char digest[128] = {0};
        char *etag = NULL;
 
-#ifdef PHP_HTTP_HAVE_HASH
-       const php_hash_ops *eho = NULL;
+       if (!strcasecmp(e->mode, "crc32b")) {
+               unsigned char buf[4];
 
-       if (e->mode && (eho = php_hash_fetch_ops(e->mode, strlen(e->mode)))) {
-               eho->hash_final(digest, e->ctx);
-               etag = php_http_etag_digest(digest, eho->digest_size);
-       } else
-#endif
-       if (((!strcasecmp(e->mode, "crc32")) || (!strcasecmp(e->mode, "crc32b")))) {
                *((uint *) e->ctx) = ~*((uint *) e->ctx);
-               etag = php_http_etag_digest((const unsigned char *) e->ctx, sizeof(uint));
+               buf[0] = ((unsigned char *) e->ctx)[3];
+               buf[1] = ((unsigned char *) e->ctx)[2];
+               buf[2] = ((unsigned char *) e->ctx)[1];
+               buf[3] = ((unsigned char *) e->ctx)[0];
+               etag = php_http_etag_digest(buf, 4);
        } else if ((!strcasecmp(e->mode, "sha1"))) {
                PHP_SHA1Final(digest, e->ctx);
                etag = php_http_etag_digest(digest, 20);
-       } else {
+       } else if ((!strcasecmp(e->mode, "md5"))) {
                PHP_MD5Final(digest, e->ctx);
                etag = php_http_etag_digest(digest, 16);
+       } else {
+#ifdef PHP_HTTP_HAVE_HASH
+               const php_hash_ops *eho = NULL;
+
+               if (e->mode && (eho = php_hash_fetch_ops(e->mode, strlen(e->mode)))) {
+                       eho->hash_final(digest, e->ctx);
+                       etag = php_http_etag_digest(digest, eho->digest_size);
+               }
+#endif
        }
+
        efree(e->ctx);
        efree(e->mode);
        efree(e);
@@ -84,14 +92,7 @@ PHP_HTTP_API char *php_http_etag_finish(php_http_etag_t *e)
 
 PHP_HTTP_API size_t php_http_etag_update(php_http_etag_t *e, const char *data_ptr, size_t data_len)
 {
-#ifdef PHP_HTTP_HAVE_HASH
-       const php_hash_ops *eho = NULL;
-
-       if (e->mode && (eho = php_hash_fetch_ops(e->mode, strlen(e->mode)))) {
-               eho->hash_update(e->ctx, (const unsigned char *) data_ptr, data_len);
-       } else
-#endif
-       if (((!strcasecmp(e->mode, "crc32")) || (!strcasecmp(e->mode, "crc32b")))) {
+       if (!strcasecmp(e->mode, "crc32b")) {
                uint i, c = *((uint *) e->ctx);
                for (i = 0; i < data_len; ++i) {
                        CRC32(c, data_ptr[i]);
@@ -99,8 +100,16 @@ PHP_HTTP_API size_t php_http_etag_update(php_http_etag_t *e, const char *data_pt
                *((uint *) e->ctx) = c;
        } else if ((!strcasecmp(e->mode, "sha1"))) {
                PHP_SHA1Update(e->ctx, (const unsigned char *) data_ptr, data_len);
-       } else {
+       } else if ((!strcasecmp(e->mode, "md5"))) {
                PHP_MD5Update(e->ctx, (const unsigned char *) data_ptr, data_len);
+       } else {
+#ifdef PHP_HTTP_HAVE_HASH
+               const php_hash_ops *eho = NULL;
+
+               if (e->mode && (eho = php_hash_fetch_ops(e->mode, strlen(e->mode)))) {
+                       eho->hash_update(e->ctx, (const unsigned char *) data_ptr, data_len);
+               }
+#endif
        }
 
        return data_len;
index c9cea55b46f640c4dab754082687c968afd1618c..7019de30e763498b2e946ffd5df3ee00d80920bf 100644 (file)
@@ -123,8 +123,12 @@ PHP_HTTP_API char *php_http_message_body_etag(php_http_message_body_t *body)
        } else {
                php_http_etag_t *etag = php_http_etag_init(PHP_HTTP_G->env.etag_mode TSRMLS_CC);
 
-               php_http_message_body_to_callback(body, (php_http_pass_callback_t) php_http_etag_update, etag, 0, 0);
-               return php_http_etag_finish(etag);
+               if (etag) {
+                       php_http_message_body_to_callback(body, (php_http_pass_callback_t) php_http_etag_update, etag, 0, 0);
+                       return php_http_etag_finish(etag);
+               } else {
+                       return NULL;
+               }
        }
 }
 
index bc07401fa2526b9b3f0e731f96ccfbe5abf0959e..eda54b0b9e416562e4ce0fc47ef585d9a73af03e 100644 (file)
@@ -87,7 +87,7 @@ class MessageBodyTest extends PHPUnit_Framework_TestCase {
             ),
             $this->file->etag()
         );
-        $this->assertEquals(md5(""), $this->temp->etag());
+        $this->assertEquals(crc32(""), $this->temp->etag());
     }
 
     function testToStream() {
diff --git a/tests/etag001.phpt b/tests/etag001.phpt
new file mode 100644 (file)
index 0000000..40b578d
--- /dev/null
@@ -0,0 +1,64 @@
+--TEST--
+etags with hash
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--EXTENSIONS--
+hash
+--FILE--
+<?php
+$body = new http\Message\Body;
+$body->append("Hello, my old fellow.");
+foreach (hash_algos() as $algo) {
+    ini_set("http.etag.mode", $algo);
+    printf("%10s: %s\n", 
+        $algo, 
+        $body->etag()
+    );
+}
+?>
+DONE
+--EXPECT--
+       md2: 9bf7d8506d7453a85dc34fa730cbc16a
+       md4: 137008b9144843f5bfcc6651688acc41
+       md5: 6ce3cc8f3861fb7fd0d77739f11cd29c
+      sha1: ad84012eabe27a61762a97138d9d2623f4f1a7a9
+    sha224: 91be9bd30cec7fb7fb0279e40211fa71f8a7ab933f9f1a832d7c60cb
+    sha256: ed9ecfe5c76d51179c3c1065916fdb8d94aee05577f187bd763cdc962bba1f42
+    sha384: 923a756152da113db192958da485c7881e7c4811d2d34e22f4d74cd45310d983f7fb1c5527a5f9037a4c7b649a6cc2b2
+    sha512: ad5ea693b8df4457d08d835ad5ccf7b626b66285f8424b3ec59e54c63bf63feef9a92baaba71c38d7bd9a1135488499fc835a8818390965c9ce8a5e4c40e519f
+ ripemd128: b9e8d5864b5821d72e66101a9a0e730a
+ ripemd160: d697a33676aece781b72f6fcb95f4c730367706b
+ ripemd256: 9c3a73ab03e6d7d3471cf70316c4ff3ec56212d25730d382fb1480346529742b
+ ripemd320: 5a6ee6b7c35c64d9c91019b9a1ceb2ab2ae19915f3dc96b0f244e15581d750a775a3682c5e70ee23
+ whirlpool: 2cb738084edaede8b36e9c8d81f5d30d9afe12bf60715073a6651c32c3448a6eeeff9f9715a8c996291ab3cd6c9a9caac8bea3b0eeb1c88afe6ad46fdd0cef83
+tiger128,3: f3055bdb40b06abac716a27a654b295d
+tiger160,3: f3055bdb40b06abac716a27a654b295dc07e1ab9
+tiger192,3: f3055bdb40b06abac716a27a654b295dc07e1ab915b56529
+tiger128,4: e6a1628a4da8fa6adf4ca866c5e235b5
+tiger160,4: e6a1628a4da8fa6adf4ca866c5e235b51939bb61
+tiger192,4: e6a1628a4da8fa6adf4ca866c5e235b51939bb61ecf8423f
+    snefru: 8f50c66c8f0a1510f9c591a2b7a070853d4770c60a38394c8857918dd91a2e5b
+ snefru256: 8f50c66c8f0a1510f9c591a2b7a070853d4770c60a38394c8857918dd91a2e5b
+      gost: efc79cdd01331adf80b30af816ff7a934f3f3df3085294a310918cacff3500f0
+   adler32: 4ff5075d
+     crc32: 757b06f7
+    crc32b: e56655c5
+    fnv132: ebd1fa1f
+    fnv164: 9790ce01eba3ae9f
+     joaat: 70a407c9
+haval128,3: 68a1bee33d2a4fa5543be7fa871f84ea
+haval160,3: b4204e8c4f3c993385d997539afa723888700bbd
+haval192,3: 6c7f3442f5b5c7d338bd31ab9de1216576ce6633f8de9e03
+haval224,3: 4edf7debeea48b94af73f47c1a4449dff516b69ba36f6659ed59689c
+haval256,3: eb919a27c9e598cf3559e79fca10119d54b6f704b779cd665ab5352eb17726c4
+haval128,4: 184195034f2e5b2a0d04dcc42fac3275
+haval160,4: b13d521378d7b74b226430355fa6f4ceba0782c2
+haval192,4: 4e53f767e7dbff4abb8ebf767d672db3df77de7d9de6e9d9
+haval224,4: 1208cc9fc1c23de3985f5a5214ebb67c846cecd32f96d950ef3ef770
+haval256,4: 658d40b21f87ebe45cf6ec822402d1ca6965f263358e3927a92beba837785735
+haval128,5: 938933eefe94e217d73a27909f89f8c6
+haval160,5: 07b9e4a6c451acb5930081f414a06d948c1b70ba
+haval192,5: 997ca1515369b0051e9fcc736c1096618ef936f185a19ebe
+haval224,5: b46f2aada87d9e7a38b126268dce9779303aa4999d42f5c74427e362
+haval256,5: 4e0b601e5ee93d6c2a449793e756e9ca6e03fb618c9f2ed849a7f8ca29ef9112
+DONE