2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2014, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
13 #include "php_http_api.h"
15 #ifdef PHP_HTTP_HAVE_HASH
16 # include "php_hash.h"
19 #include <ext/standard/crc32.h>
20 #include <ext/standard/sha1.h>
21 #include <ext/standard/md5.h>
23 php_http_etag_t
*php_http_etag_init(const char *mode
)
28 if (mode
&& (!strcasecmp(mode
, "crc32b"))) {
29 ctx
= emalloc(sizeof(uint
));
31 } else if (mode
&& !strcasecmp(mode
, "sha1")) {
32 PHP_SHA1Init(ctx
= emalloc(sizeof(PHP_SHA1_CTX
)));
33 } else if (mode
&& !strcasecmp(mode
, "md5")) {
34 PHP_MD5Init(ctx
= emalloc(sizeof(PHP_MD5_CTX
)));
36 #ifdef PHP_HTTP_HAVE_HASH
37 const php_hash_ops
*eho
= NULL
;
39 if (mode
&& (eho
= php_hash_fetch_ops(mode
, strlen(mode
)))) {
40 ctx
= emalloc(eho
->context_size
);
47 e
= emalloc(sizeof(*e
));
49 e
->mode
= estrdup(mode
);
54 char *php_http_etag_finish(php_http_etag_t
*e
)
56 unsigned char digest
[128] = {0};
59 if (!strcasecmp(e
->mode
, "crc32b")) {
62 *((uint
*) e
->ctx
) = ~*((uint
*) e
->ctx
);
63 #ifdef WORDS_BIGENDIAN
64 etag
= php_http_etag_digest((unsigned char *) e
->ctx
, 4);
66 buf
[0] = ((unsigned char *) e
->ctx
)[3];
67 buf
[1] = ((unsigned char *) e
->ctx
)[2];
68 buf
[2] = ((unsigned char *) e
->ctx
)[1];
69 buf
[3] = ((unsigned char *) e
->ctx
)[0];
70 etag
= php_http_etag_digest(buf
, 4);
72 } else if ((!strcasecmp(e
->mode
, "sha1"))) {
73 PHP_SHA1Final(digest
, e
->ctx
);
74 etag
= php_http_etag_digest(digest
, 20);
75 } else if ((!strcasecmp(e
->mode
, "md5"))) {
76 PHP_MD5Final(digest
, e
->ctx
);
77 etag
= php_http_etag_digest(digest
, 16);
79 #ifdef PHP_HTTP_HAVE_HASH
80 const php_hash_ops
*eho
= NULL
;
82 if (e
->mode
&& (eho
= php_hash_fetch_ops(e
->mode
, strlen(e
->mode
)))) {
83 eho
->hash_final(digest
, e
->ctx
);
84 etag
= php_http_etag_digest(digest
, eho
->digest_size
);
96 size_t php_http_etag_update(php_http_etag_t
*e
, const char *data_ptr
, size_t data_len
)
98 if (!strcasecmp(e
->mode
, "crc32b")) {
99 uint i
, c
= *((uint
*) e
->ctx
);
100 for (i
= 0; i
< data_len
; ++i
) {
101 CRC32(c
, data_ptr
[i
]);
103 *((uint
*) e
->ctx
) = c
;
104 } else if ((!strcasecmp(e
->mode
, "sha1"))) {
105 PHP_SHA1Update(e
->ctx
, (const unsigned char *) data_ptr
, data_len
);
106 } else if ((!strcasecmp(e
->mode
, "md5"))) {
107 PHP_MD5Update(e
->ctx
, (const unsigned char *) data_ptr
, data_len
);
109 #ifdef PHP_HTTP_HAVE_HASH
110 const php_hash_ops
*eho
= NULL
;
112 if (e
->mode
&& (eho
= php_hash_fetch_ops(e
->mode
, strlen(e
->mode
)))) {
113 eho
->hash_update(e
->ctx
, (const unsigned char *) data_ptr
, data_len
);
127 * vim600: noet sw=4 ts=4 fdm=marker
128 * vim<600: noet sw=4 ts=4