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 TSRMLS_DC
)
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
);
50 TSRMLS_SET_CTX(e
->ts
);
55 char *php_http_etag_finish(php_http_etag_t
*e
)
57 unsigned char digest
[128] = {0};
60 if (!strcasecmp(e
->mode
, "crc32b")) {
63 *((uint
*) e
->ctx
) = ~*((uint
*) e
->ctx
);
64 #ifdef WORDS_BIGENDIAN
65 etag
= php_http_etag_digest((unsigned char *) e
->ctx
, 4);
67 buf
[0] = ((unsigned char *) e
->ctx
)[3];
68 buf
[1] = ((unsigned char *) e
->ctx
)[2];
69 buf
[2] = ((unsigned char *) e
->ctx
)[1];
70 buf
[3] = ((unsigned char *) e
->ctx
)[0];
71 etag
= php_http_etag_digest(buf
, 4);
73 } else if ((!strcasecmp(e
->mode
, "sha1"))) {
74 PHP_SHA1Final(digest
, e
->ctx
);
75 etag
= php_http_etag_digest(digest
, 20);
76 } else if ((!strcasecmp(e
->mode
, "md5"))) {
77 PHP_MD5Final(digest
, e
->ctx
);
78 etag
= php_http_etag_digest(digest
, 16);
80 #ifdef PHP_HTTP_HAVE_HASH
81 const php_hash_ops
*eho
= NULL
;
83 if ((eho
= php_hash_fetch_ops(e
->mode
, strlen(e
->mode
)))) {
84 eho
->hash_final(digest
, e
->ctx
);
85 etag
= php_http_etag_digest(digest
, eho
->digest_size
);
97 size_t php_http_etag_update(php_http_etag_t
*e
, const char *data_ptr
, size_t data_len
)
99 if (!strcasecmp(e
->mode
, "crc32b")) {
100 uint i
, c
= *((uint
*) e
->ctx
);
101 for (i
= 0; i
< data_len
; ++i
) {
102 CRC32(c
, data_ptr
[i
]);
104 *((uint
*) e
->ctx
) = c
;
105 } else if ((!strcasecmp(e
->mode
, "sha1"))) {
106 PHP_SHA1Update(e
->ctx
, (const unsigned char *) data_ptr
, data_len
);
107 } else if ((!strcasecmp(e
->mode
, "md5"))) {
108 PHP_MD5Update(e
->ctx
, (const unsigned char *) data_ptr
, data_len
);
110 #ifdef PHP_HTTP_HAVE_HASH
111 const php_hash_ops
*eho
= NULL
;
113 if ((eho
= php_hash_fetch_ops(e
->mode
, strlen(e
->mode
)))) {
114 eho
->hash_update(e
->ctx
, (const unsigned char *) data_ptr
, data_len
);
128 * vim600: noet sw=4 ts=4 fdm=marker
129 * vim<600: noet sw=4 ts=4