Line data Source code
1 : /*
2 : +--------------------------------------------------------------------+
3 : | PECL :: http |
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 : +--------------------------------------------------------------------+
11 : */
12 :
13 : #include "php_http_api.h"
14 :
15 : #ifdef PHP_HTTP_HAVE_HASH
16 : # include "php_hash.h"
17 : #endif
18 :
19 : #include <ext/standard/crc32.h>
20 : #include <ext/standard/sha1.h>
21 : #include <ext/standard/md5.h>
22 :
23 51 : php_http_etag_t *php_http_etag_init(const char *mode TSRMLS_DC)
24 : {
25 : void *ctx;
26 : php_http_etag_t *e;
27 :
28 51 : if (mode && (!strcasecmp(mode, "crc32b"))) {
29 9 : ctx = emalloc(sizeof(uint));
30 9 : *((uint *) ctx) = ~0;
31 42 : } else if (mode && !strcasecmp(mode, "sha1")) {
32 1 : PHP_SHA1Init(ctx = emalloc(sizeof(PHP_SHA1_CTX)));
33 41 : } else if (mode && !strcasecmp(mode, "md5")) {
34 1 : PHP_MD5Init(ctx = emalloc(sizeof(PHP_MD5_CTX)));
35 : } else {
36 : #ifdef PHP_HTTP_HAVE_HASH
37 40 : const php_hash_ops *eho = NULL;
38 :
39 40 : if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) {
40 40 : ctx = emalloc(eho->context_size);
41 40 : eho->hash_init(ctx);
42 : } else
43 : #endif
44 0 : return NULL;
45 : }
46 :
47 51 : e = emalloc(sizeof(*e));
48 51 : e->ctx = ctx;
49 51 : e->mode = estrdup(mode);
50 : TSRMLS_SET_CTX(e->ts);
51 :
52 51 : return e;
53 : }
54 :
55 51 : char *php_http_etag_finish(php_http_etag_t *e)
56 : {
57 51 : unsigned char digest[128] = {0};
58 51 : char *etag = NULL;
59 :
60 51 : if (!strcasecmp(e->mode, "crc32b")) {
61 : unsigned char buf[4];
62 :
63 9 : *((uint *) e->ctx) = ~*((uint *) e->ctx);
64 : #ifdef WORDS_BIGENDIAN
65 : etag = php_http_etag_digest((unsigned char *) e->ctx, 4);
66 : #else
67 9 : buf[0] = ((unsigned char *) e->ctx)[3];
68 9 : buf[1] = ((unsigned char *) e->ctx)[2];
69 9 : buf[2] = ((unsigned char *) e->ctx)[1];
70 9 : buf[3] = ((unsigned char *) e->ctx)[0];
71 9 : etag = php_http_etag_digest(buf, 4);
72 : #endif
73 42 : } else if ((!strcasecmp(e->mode, "sha1"))) {
74 1 : PHP_SHA1Final(digest, e->ctx);
75 1 : etag = php_http_etag_digest(digest, 20);
76 41 : } else if ((!strcasecmp(e->mode, "md5"))) {
77 1 : PHP_MD5Final(digest, e->ctx);
78 1 : etag = php_http_etag_digest(digest, 16);
79 : } else {
80 : #ifdef PHP_HTTP_HAVE_HASH
81 40 : const php_hash_ops *eho = NULL;
82 :
83 40 : if (e->mode && (eho = php_hash_fetch_ops(e->mode, strlen(e->mode)))) {
84 40 : eho->hash_final(digest, e->ctx);
85 40 : etag = php_http_etag_digest(digest, eho->digest_size);
86 : }
87 : #endif
88 : }
89 :
90 51 : efree(e->ctx);
91 51 : efree(e->mode);
92 51 : efree(e);
93 :
94 51 : return etag;
95 : }
96 :
97 32818 : size_t php_http_etag_update(php_http_etag_t *e, const char *data_ptr, size_t data_len)
98 : {
99 32818 : if (!strcasecmp(e->mode, "crc32b")) {
100 32776 : uint i, c = *((uint *) e->ctx);
101 134250810 : for (i = 0; i < data_len; ++i) {
102 134218034 : CRC32(c, data_ptr[i]);
103 : }
104 32776 : *((uint *) e->ctx) = c;
105 42 : } else if ((!strcasecmp(e->mode, "sha1"))) {
106 1 : PHP_SHA1Update(e->ctx, (const unsigned char *) data_ptr, data_len);
107 41 : } else if ((!strcasecmp(e->mode, "md5"))) {
108 1 : PHP_MD5Update(e->ctx, (const unsigned char *) data_ptr, data_len);
109 : } else {
110 : #ifdef PHP_HTTP_HAVE_HASH
111 40 : const php_hash_ops *eho = NULL;
112 :
113 40 : if (e->mode && (eho = php_hash_fetch_ops(e->mode, strlen(e->mode)))) {
114 40 : eho->hash_update(e->ctx, (const unsigned char *) data_ptr, data_len);
115 : }
116 : #endif
117 : }
118 :
119 32818 : return data_len;
120 : }
121 :
122 :
123 : /*
124 : * Local variables:
125 : * tab-width: 4
126 : * c-basic-offset: 4
127 : * End:
128 : * vim600: noet sw=4 ts=4 fdm=marker
129 : * vim<600: noet sw=4 ts=4
130 : */
131 :
|