a15a0db85e884a4f887ab6b0edecf108ca818a5e
[m6w6/ext-http] / http_querystring_api.c
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-2006, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 /* $Id$ */
14
15 #define HTTP_WANT_SAPI
16 #include "php_http.h"
17
18 #include "php_variables.h"
19 #ifdef HAVE_ICONV
20 # undef PHP_ATOM_INC
21 # include "ext/iconv/php_iconv.h"
22 # include "ext/standard/url.h"
23 #endif
24
25 #include "php_http_api.h"
26 #include "php_http_url_api.h"
27 #include "php_http_querystring_api.h"
28
29 #ifdef ZEND_ENGINE_2
30 #define OBJ_PROP_CE http_querystring_object_ce
31 extern zend_class_entry *http_querystring_object_ce;
32 #endif
33
34 #ifdef HAVE_ICONV
35 PHP_HTTP_API int _http_querystring_xlate(zval *array, zval *param, const char *ie, const char *oe TSRMLS_DC)
36 {
37 HashPosition pos;
38 zval **entry = NULL;
39 char *xlate_str = NULL, *xkey, *kstr = NULL;
40 size_t xlate_len = 0, xlen;
41 uint klen = 0;
42 ulong kidx = 0;
43
44 FOREACH_KEYLENVAL(pos, param, kstr, klen, kidx, entry) {
45 if (kstr) {
46 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(kstr, klen-1, &xkey, &xlen, oe, ie)) {
47 http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", klen-1, kstr, ie, oe);
48 return FAILURE;
49 }
50 }
51
52 if (Z_TYPE_PP(entry) == IS_STRING) {
53 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), &xlate_str, &xlate_len, oe, ie)) {
54 if (kstr) {
55 efree(xkey);
56 }
57 http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_PP(entry), Z_STRVAL_PP(entry), ie, oe);
58 return FAILURE;
59 }
60 if (kstr) {
61 add_assoc_stringl_ex(array, xkey, xlen+1, xlate_str, xlate_len, 0);
62 } else {
63 add_index_stringl(array, kidx, xlate_str, xlate_len, 0);
64 }
65 } else if (Z_TYPE_PP(entry) == IS_ARRAY) {
66 zval *subarray;
67
68 MAKE_STD_ZVAL(subarray);
69 array_init(subarray);
70 if (kstr) {
71 add_assoc_zval_ex(array, xkey, xlen+1, subarray);
72 } else {
73 add_index_zval(array, kidx, subarray);
74 }
75 if (SUCCESS != http_querystring_xlate(subarray, *entry, ie, oe)) {
76 if (kstr) {
77 efree(xkey);
78 }
79 return FAILURE;
80 }
81 }
82
83 if (kstr) {
84 kstr = NULL;
85 efree(xkey);
86 }
87 }
88 return SUCCESS;
89 }
90 #endif /* HAVE_ICONV */
91
92 PHP_HTTP_API void _http_querystring_update(zval *qarray, zval *qstring TSRMLS_DC)
93 {
94 char *s = NULL;
95 size_t l = 0;
96
97 if (Z_TYPE_P(qarray) != IS_ARRAY) {
98 convert_to_array(qarray);
99 }
100 if (SUCCESS == http_urlencode_hash_ex(Z_ARRVAL_P(qarray), 0, NULL, 0, &s, &l)) {
101 zval_dtor(qstring);
102 ZVAL_STRINGL(qstring, s, l, 0);
103 } else {
104 http_error(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to update query string");
105 }
106 }
107
108 PHP_HTTP_API int _http_querystring_modify_array_ex(zval *qarray, int key_type, char *key, int keylen, ulong idx, zval *params_entry TSRMLS_DC)
109 {
110 zval **qarray_entry;
111
112 /* delete */
113 if (Z_TYPE_P(params_entry) == IS_NULL) {
114 if (key_type == HASH_KEY_IS_STRING) {
115 return (SUCCESS == zend_hash_del(Z_ARRVAL_P(qarray), key, keylen));
116 } else {
117 return (SUCCESS == zend_hash_index_del(Z_ARRVAL_P(qarray), idx));
118 }
119 }
120
121 /* update */
122 if ( ((key_type == HASH_KEY_IS_STRING) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), key, keylen, (void *) &qarray_entry))) ||
123 ((key_type == HASH_KEY_IS_LONG) && (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(qarray), idx, (void *) &qarray_entry)))) {
124 zval equal;
125
126 /* recursive */
127 if (Z_TYPE_P(params_entry) == IS_ARRAY) {
128 return http_querystring_modify_array(*qarray_entry, params_entry);
129 }
130 /* equal */
131 if ((SUCCESS == is_equal_function(&equal, *qarray_entry, params_entry TSRMLS_CC)) && Z_BVAL(equal)) {
132 return 0;
133 }
134 }
135
136 /* add */
137 ZVAL_ADDREF(params_entry);
138 if (key_type == HASH_KEY_IS_STRING) {
139 add_assoc_zval_ex(qarray, key, keylen, params_entry);
140 } else {
141 add_index_zval(qarray, idx, params_entry);
142 }
143 return 1;
144 }
145
146 PHP_HTTP_API int _http_querystring_modify_array(zval *qarray, zval *params TSRMLS_DC)
147 {
148 int rv = 0;
149 char *key = NULL;
150 uint keylen = 0;
151 ulong idx = 0;
152 HashPosition pos;
153 zval **params_entry = NULL;
154
155 FOREACH_KEYLENVAL(pos, params, key, keylen, idx, params_entry) {
156 if (http_querystring_modify_array_ex(qarray, key ? HASH_KEY_IS_STRING : HASH_KEY_IS_LONG, key, keylen, idx, *params_entry)) {
157 rv = 1;
158 }
159 key = NULL;
160 }
161
162 return rv;
163 }
164
165 PHP_HTTP_API int _http_querystring_modify(zval *qarray, zval *params TSRMLS_DC)
166 {
167 if (Z_TYPE_P(params) == IS_ARRAY) {
168 return http_querystring_modify_array(qarray, params);
169 } else if (Z_TYPE_P(params) == IS_OBJECT) {
170 #ifdef ZEND_ENGINE_2
171 if (!instanceof_function(Z_OBJCE_P(params), http_querystring_object_ce TSRMLS_CC)) {
172 #endif
173 zval temp_array;
174 INIT_ZARR(temp_array, HASH_OF(params));
175 return http_querystring_modify_array(qarray, &temp_array);
176 #ifdef ZEND_ENGINE_2
177 }
178 return http_querystring_modify_array(qarray, GET_PROP_EX(params, queryArray));
179 #endif
180 } else {
181 int rv;
182 zval array;
183
184 INIT_PZVAL(&array);
185 array_init(&array);
186
187 ZVAL_ADDREF(params);
188 convert_to_string_ex(&params);
189 sapi_module.treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(params)), &array TSRMLS_CC);
190 zval_ptr_dtor(&params);
191 rv = http_querystring_modify_array(qarray, &array);
192 zval_dtor(&array);
193 return rv;
194 }
195 }
196
197 /*
198 * Local variables:
199 * tab-width: 4
200 * c-basic-offset: 4
201 * End:
202 * vim600: noet sw=4 ts=4 fdm=marker
203 * vim<600: noet sw=4 ts=4
204 */