X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Fphp_http_etag.c;h=048af87c8b63a60fd881a0cb319b3637f64f6549;hb=e3976774f27b4129cbfd7d227aaa7e177f1b735c;hp=eb3b5e35b11527f30a84b305c4308b17354c3b7b;hpb=e44e3ceb60817cfdd17945a3f6043816e134aa75;p=m6w6%2Fext-http diff --git a/src/php_http_etag.c b/src/php_http_etag.c index eb3b5e3..048af87 100644 --- a/src/php_http_etag.c +++ b/src/php_http_etag.c @@ -12,26 +12,41 @@ #include "php_http_api.h" -#include "ext/hash/php_hash.h" +#if PHP_HTTP_HAVE_HASH +# include "ext/hash/php_hash.h" +#endif + #include "ext/standard/crc32.h" #include "ext/standard/sha1.h" #include "ext/standard/md5.h" php_http_etag_t *php_http_etag_init(const char *mode) { + void *ctx; php_http_etag_t *e; - zend_string *mode_str = zend_string_init(mode, strlen(mode), 0); - const php_hash_ops *eho = php_hash_fetch_ops(mode_str); - if (!eho) { - zend_string_release(mode_str); + if (mode && (!strcasecmp(mode, "crc32b"))) { + ctx = emalloc(sizeof(uint32_t)); + *((uint32_t *) ctx) = ~0; + } else if (mode && !strcasecmp(mode, "sha1")) { + PHP_SHA1Init(ctx = emalloc(sizeof(PHP_SHA1_CTX))); + } else if (mode && !strcasecmp(mode, "md5")) { + PHP_MD5Init(ctx = emalloc(sizeof(PHP_MD5_CTX))); + } else { +#if 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; } - zend_string_release(mode_str); - e = emalloc(sizeof(*e) + eho->context_size - 1); - e->ops = eho; - eho->hash_init(e->ctx); + e = emalloc(sizeof(*e)); + e->ctx = ctx; + e->mode = estrdup(mode); return e; } @@ -39,10 +54,32 @@ php_http_etag_t *php_http_etag_init(const char *mode) char *php_http_etag_finish(php_http_etag_t *e) { unsigned char digest[128] = {0}; - char *etag; + char *etag = NULL; - e->ops->hash_final(digest, e->ctx); - etag = php_http_etag_digest(digest, e->ops->digest_size); + if (!strcasecmp(e->mode, "crc32b")) { + uint32_t e_ctx; + memcpy(&e_ctx, e->ctx, 4); + e_ctx = ntohl(~e_ctx); + etag = php_http_etag_digest((unsigned char *) &e_ctx, 4); + } else if ((!strcasecmp(e->mode, "sha1"))) { + PHP_SHA1Final(digest, e->ctx); + etag = php_http_etag_digest(digest, 20); + } else if ((!strcasecmp(e->mode, "md5"))) { + PHP_MD5Final(digest, e->ctx); + etag = php_http_etag_digest(digest, 16); + } else { +#if PHP_HTTP_HAVE_HASH + const php_hash_ops *eho = NULL; + + if ((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); return etag; @@ -50,7 +87,25 @@ char *php_http_etag_finish(php_http_etag_t *e) size_t php_http_etag_update(php_http_etag_t *e, const char *data_ptr, size_t data_len) { - e->ops->hash_update(e->ctx, (const unsigned char *) data_ptr, data_len); + if (!strcasecmp(e->mode, "crc32b")) { + uint32_t i, c = *((uint32_t *) e->ctx); + for (i = 0; i < data_len; ++i) { + CRC32(c, data_ptr[i]); + } + *((uint32_t *) e->ctx) = c; + } else if ((!strcasecmp(e->mode, "sha1"))) { + PHP_SHA1Update(e->ctx, (const unsigned char *) data_ptr, data_len); + } else if ((!strcasecmp(e->mode, "md5"))) { + PHP_MD5Update(e->ctx, (const unsigned char *) data_ptr, data_len); + } else { +#if PHP_HTTP_HAVE_HASH + const php_hash_ops *eho = NULL; + + if ((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; }