code cleanup
[m6w6/ext-http] / php_http_cookie.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-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #include "php_http_api.h"
14
15 PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_init(php_http_cookie_list_t *list TSRMLS_DC)
16 {
17 if (!list) {
18 list = emalloc(sizeof(*list));
19 }
20
21 zend_hash_init(&list->cookies, 0, NULL, ZVAL_PTR_DTOR, 0);
22 zend_hash_init(&list->extras, 0, NULL, ZVAL_PTR_DTOR, 0);
23
24 list->path = NULL;
25 list->domain = NULL;
26 list->expires = -1;
27 list->flags = 0;
28
29 TSRMLS_SET_CTX(list->ts);
30
31 return list;
32 }
33
34 PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_copy(php_http_cookie_list_t *from, php_http_cookie_list_t *to)
35 {
36 TSRMLS_FETCH_FROM_CTX(from->ts);
37
38 to = php_http_cookie_list_init(to TSRMLS_CC);
39
40 array_copy(&from->cookies, &to->cookies);
41 array_copy(&from->extras, &to->extras);
42
43 STR_SET(to->path, from->path ? estrdup(from->path) : NULL);
44 STR_SET(to->domain, from->domain ? estrdup(from->domain) : NULL);
45 to->expires = from->expires;
46 to->flags = from->flags;
47
48 return to;
49 }
50
51 PHP_HTTP_API void php_http_cookie_list_dtor(php_http_cookie_list_t *list)
52 {
53 if (list) {
54 zend_hash_destroy(&list->cookies);
55 zend_hash_destroy(&list->extras);
56
57 STR_SET(list->path, NULL);
58 STR_SET(list->domain, NULL);
59 }
60 }
61
62
63
64 PHP_HTTP_API void php_http_cookie_list_free(php_http_cookie_list_t **list)
65 {
66 if (*list) {
67 php_http_cookie_list_dtor(*list);
68 efree(*list);
69 *list = NULL;
70 }
71 }
72
73
74
75 PHP_HTTP_API const char *php_http_cookie_list_get_cookie(php_http_cookie_list_t *list, const char *name, size_t name_len)
76 {
77 zval **cookie = NULL;
78 if ((SUCCESS != zend_symtable_find(&list->cookies, name, name_len + 1, (void *) &cookie)) || (Z_TYPE_PP(cookie) != IS_STRING)) {
79 return NULL;
80 }
81 return Z_STRVAL_PP(cookie);
82 }
83
84
85
86 PHP_HTTP_API const char *php_http_cookie_list_get_extra(php_http_cookie_list_t *list, const char *name, size_t name_len)
87 {
88 zval **extra = NULL;
89 if ((SUCCESS != zend_symtable_find(&list->extras, name, name_len + 1, (void *) &extra)) || (Z_TYPE_PP(extra) != IS_STRING)) {
90 return NULL;
91 }
92 return Z_STRVAL_PP(extra);
93 }
94
95
96
97 PHP_HTTP_API void php_http_cookie_list_add_cookie(php_http_cookie_list_t *list, const char *name, size_t name_len, const char *value, size_t value_len)
98 {
99 zval *cookie_value;
100
101 MAKE_STD_ZVAL(cookie_value);
102 ZVAL_STRINGL(cookie_value, estrndup(value, value_len), value_len, 0);
103 zend_symtable_update(&list->cookies, name, name_len + 1, (void *) &cookie_value, sizeof(zval *), NULL);
104 }
105
106
107
108 PHP_HTTP_API void php_http_cookie_list_add_extra(php_http_cookie_list_t *list, const char *name, size_t name_len, const char *value, size_t value_len)
109 {
110 zval *cookie_value;
111
112 MAKE_STD_ZVAL(cookie_value);
113 ZVAL_STRINGL(cookie_value, estrndup(value, value_len), value_len, 0);
114 zend_symtable_update(&list->extras, name, name_len + 1, (void *) &cookie_value, sizeof(zval *), NULL);
115 }
116
117 #define _KEY_IS(s) (key->len == sizeof(s) && !strncasecmp(key->str, (s), key->len))
118 static void add_entry(php_http_cookie_list_t *list, char **allowed_extras, long flags, php_http_array_hashkey_t *key, zval *val)
119 {
120 zval *arg = php_http_zsep(1, IS_STRING, val);
121
122 if (!(flags & PHP_HTTP_COOKIE_PARSE_RAW)) {
123 Z_STRLEN_P(arg) = php_raw_url_decode(Z_STRVAL_P(arg), Z_STRLEN_P(arg));
124 }
125
126 if _KEY_IS("path") {
127 STR_SET(list->path, estrndup(Z_STRVAL_P(arg), Z_STRLEN_P(arg)));
128 } else if _KEY_IS("domain") {
129 STR_SET(list->domain, estrndup(Z_STRVAL_P(arg), Z_STRLEN_P(arg)));
130 } else if _KEY_IS("expires") {
131 char *date = estrndup(Z_STRVAL_P(arg), Z_STRLEN_P(arg));
132 list->expires = php_parse_date(date, NULL);
133 efree(date);
134 } else if _KEY_IS("secure") {
135 list->flags |= PHP_HTTP_COOKIE_SECURE;
136 } else if _KEY_IS("httpOnly") {
137 list->flags |= PHP_HTTP_COOKIE_HTTPONLY;
138 } else {
139 char buf[0x20], *key_str;
140 int key_len;
141
142 if (key->type == HASH_KEY_IS_LONG) {
143 key_len = slprintf(buf, sizeof(buf) - 1, "%ld", key->num) + 1;
144 key_str = &buf[0];
145 } else {
146 key_len = key->len;
147 key_str = key->str;
148 }
149 /* check for extra */
150 if (allowed_extras) {
151 char **ae = allowed_extras;
152
153 for (; *ae; ++ae) {
154 if (!strncasecmp(key_str, *ae, key_len)) {
155 if (key->type == HASH_KEY_IS_LONG) {
156 zend_hash_index_update(&list->extras, key->num, (void *) &arg, sizeof(zval *), NULL);
157 } else {
158 zend_hash_update(&list->extras, key->str, key->len, (void *) &arg, sizeof(zval *), NULL);
159 }
160 return;
161 }
162 }
163 }
164
165 /* cookie */
166 if (key->type == HASH_KEY_IS_LONG) {
167 zend_hash_index_update(&list->cookies, key->num, (void *) &arg, sizeof(zval *), NULL);
168 } else {
169 zend_hash_update(&list->cookies, key->str, key->len, (void *) &arg, sizeof(zval *), NULL);
170 }
171 return;
172 }
173 zval_ptr_dtor(&arg);
174 }
175
176 PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_parse(php_http_cookie_list_t *list, const char *str, size_t len, long flags, char **allowed_extras TSRMLS_DC)
177 {
178 php_http_params_opts_t opts;
179 HashTable params;
180 HashPosition pos1, pos2;
181 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
182 zval **param, **val, **args, **arg;
183
184 php_http_params_opts_default_get(&opts);
185 opts.input.str = estrndup(str, len);
186 opts.input.len = len;
187 opts.param = NULL;
188 zend_hash_init(&params, 10, NULL, ZVAL_PTR_DTOR, 0);
189 php_http_params_parse(&params, &opts TSRMLS_CC);
190 efree(opts.input.str);
191
192 list = php_http_cookie_list_init(list TSRMLS_CC);
193 FOREACH_HASH_KEYVAL(pos1, &params, key, param) {
194 if (Z_TYPE_PP(param) == IS_ARRAY) {
195 if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(param), ZEND_STRS("value"), (void *) &val)) {
196 add_entry(list, NULL, flags, &key, *val);
197 }
198 if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(param), ZEND_STRS("arguments"), (void *) &args) && Z_TYPE_PP(args) == IS_ARRAY) {
199 FOREACH_KEYVAL(pos2, *args, key, arg) {
200 add_entry(list, allowed_extras, flags, &key, *arg);
201 }
202 }
203 }
204 }
205 zend_hash_destroy(&params);
206
207 return list;
208 }
209
210
211 PHP_HTTP_API void php_http_cookie_list_to_struct(php_http_cookie_list_t *list, zval *strct)
212 {
213 zval array, *cookies, *extras;
214 TSRMLS_FETCH_FROM_CTX(list->ts);
215
216 INIT_PZVAL_ARRAY(&array, HASH_OF(strct));
217
218 MAKE_STD_ZVAL(cookies);
219 array_init(cookies);
220 zend_hash_copy(Z_ARRVAL_P(cookies), &list->cookies, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
221 add_assoc_zval(&array, "cookies", cookies);
222
223 MAKE_STD_ZVAL(extras);
224 array_init(extras);
225 zend_hash_copy(Z_ARRVAL_P(extras), &list->extras, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
226 add_assoc_zval(&array, "extras", extras);
227
228 add_assoc_long(&array, "flags", list->flags);
229 add_assoc_long(&array, "expires", (long) list->expires);
230 add_assoc_string(&array, "path", STR_PTR(list->path), 1);
231 add_assoc_string(&array, "domain", STR_PTR(list->domain), 1);
232 }
233
234 PHP_HTTP_API php_http_cookie_list_t *php_http_cookie_list_from_struct(php_http_cookie_list_t *list, zval *strct TSRMLS_DC)
235 {
236 zval **tmp, *cpy;
237 HashTable *ht = HASH_OF(strct);
238
239 list = php_http_cookie_list_init(list TSRMLS_CC);
240
241 if (SUCCESS == zend_hash_find(ht, "cookies", sizeof("cookies"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_ARRAY) {
242 zend_hash_copy(&list->cookies, Z_ARRVAL_PP(tmp), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
243 }
244 if (SUCCESS == zend_hash_find(ht, "extras", sizeof("extras"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_ARRAY) {
245 zend_hash_copy(&list->extras, Z_ARRVAL_PP(tmp), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
246 }
247 if (SUCCESS == zend_hash_find(ht, "flags", sizeof("flags"), (void *) &tmp)) {
248 cpy = php_http_ztyp(IS_LONG, *tmp);
249 list->flags = Z_LVAL_P(cpy);
250 zval_ptr_dtor(&cpy);
251 }
252 if (SUCCESS == zend_hash_find(ht, "expires", sizeof("expires"), (void *) &tmp)) {
253 if (Z_TYPE_PP(tmp) == IS_LONG) {
254 list->expires = Z_LVAL_PP(tmp);
255 } else {
256 long lval;
257
258 cpy = php_http_ztyp(IS_STRING, *tmp);
259 if (IS_LONG == is_numeric_string(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy), &lval, NULL, 0)) {
260 list->expires = lval;
261 } else {
262 list->expires = php_parse_date(Z_STRVAL_P(cpy), NULL);
263 }
264
265 zval_ptr_dtor(&cpy);
266 }
267 }
268 if (SUCCESS == zend_hash_find(ht, "path", sizeof("path"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_STRING) {
269 list->path = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
270 }
271 if (SUCCESS == zend_hash_find(ht, "domain", sizeof("domain"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_STRING) {
272 list->domain = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
273 }
274
275 return list;
276 }
277
278
279
280 static inline void append_encoded(php_http_buffer_t *buf, const char *key, size_t key_len, const char *val, size_t val_len)
281 {
282 char *enc_str[2];
283 int enc_len[2];
284
285 enc_str[0] = php_raw_url_encode(key, key_len, &enc_len[0]);
286 enc_str[1] = php_raw_url_encode(val, val_len, &enc_len[1]);
287
288 php_http_buffer_append(buf, enc_str[0], enc_len[0]);
289 php_http_buffer_appends(buf, "=");
290 php_http_buffer_append(buf, enc_str[1], enc_len[1]);
291 php_http_buffer_appends(buf, "; ");
292
293 efree(enc_str[0]);
294 efree(enc_str[1]);
295 }
296
297
298
299 PHP_HTTP_API void php_http_cookie_list_to_string(php_http_cookie_list_t *list, char **str, size_t *len)
300 {
301 php_http_buffer_t buf;
302 zval **val;
303 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
304 HashPosition pos;
305 TSRMLS_FETCH_FROM_CTX(list->ts);
306
307 php_http_buffer_init(&buf);
308
309 FOREACH_HASH_KEYVAL(pos, &list->cookies, key, val) {
310 zval *tmp = php_http_ztyp(IS_STRING, *val);
311 if (key.type == HASH_KEY_IS_STRING && key.len) {
312 append_encoded(&buf, key.str, key.len-1, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
313 } else if (key.type == HASH_KEY_IS_LONG) {
314 int enc_len;
315 char *enc_str = php_raw_url_encode(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), &enc_len);
316
317 php_http_buffer_appendf(&buf, "%ld=%.*s; ", key.num, enc_len, enc_str);
318 efree(enc_str);
319 }
320 zval_ptr_dtor(&tmp);
321 }
322
323 if (list->domain && *list->domain) {
324 php_http_buffer_appendf(&buf, "domain=%s; ", list->domain);
325 }
326 if (list->path && *list->path) {
327 php_http_buffer_appendf(&buf, "path=%s; ", list->path);
328 }
329 if (list->expires >= 0) {
330 char *date = php_format_date(ZEND_STRL(PHP_HTTP_DATE_FORMAT), list->expires, 0 TSRMLS_CC);
331 php_http_buffer_appendf(&buf, "expires=%s; ", date);
332 efree(date);
333 }
334
335 FOREACH_HASH_KEYVAL(pos, &list->extras, key, val) {
336 zval *tmp = php_http_ztyp(IS_STRING, *val);
337 if (key.type == HASH_KEY_IS_STRING && key.len) {
338 append_encoded(&buf, key.str, key.len-1, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
339 } else if (key.type == HASH_KEY_IS_LONG) {
340 int enc_len;
341 char *enc_str = php_raw_url_encode(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), &enc_len);
342
343 php_http_buffer_appendf(&buf, "%ld=%.*s; ", key.num, enc_len, enc_str);
344 efree(enc_str);
345 }
346 zval_ptr_dtor(&tmp);
347 }
348
349 if (list->flags & PHP_HTTP_COOKIE_SECURE) {
350 php_http_buffer_appends(&buf, "secure; ");
351 }
352 if (list->flags & PHP_HTTP_COOKIE_HTTPONLY) {
353 php_http_buffer_appends(&buf, "httpOnly; ");
354 }
355
356 php_http_buffer_fix(&buf);
357 *str = PHP_HTTP_BUFFER_VAL(&buf);
358 *len = PHP_HTTP_BUFFER_LEN(&buf);
359 }
360
361 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpCookie, method, 0, req_args)
362 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpCookie, method, 0)
363 #define PHP_HTTP_COOKIE_ME(method, visibility) PHP_ME(HttpCookie, method, PHP_HTTP_ARGS(HttpCookie, method), visibility)
364
365 PHP_HTTP_BEGIN_ARGS(__construct, 0)
366 PHP_HTTP_ARG_VAL(cookie_string, 0)
367 PHP_HTTP_ARG_VAL(parser_flags, 0)
368 PHP_HTTP_ARG_VAL(allowed_extras, 0)
369 PHP_HTTP_END_ARGS;
370
371 PHP_HTTP_EMPTY_ARGS(toArray);
372 PHP_HTTP_EMPTY_ARGS(getCookies);
373 PHP_HTTP_EMPTY_ARGS(getExtras);
374 PHP_HTTP_EMPTY_ARGS(getDomain);
375 PHP_HTTP_EMPTY_ARGS(getPath);
376 PHP_HTTP_EMPTY_ARGS(getExpires);
377 PHP_HTTP_EMPTY_ARGS(getFlags);
378 PHP_HTTP_EMPTY_ARGS(toString);
379
380 PHP_HTTP_BEGIN_ARGS(setDomain, 0)
381 PHP_HTTP_ARG_VAL(value, 0)
382 PHP_HTTP_END_ARGS;
383 PHP_HTTP_BEGIN_ARGS(setPath, 0)
384 PHP_HTTP_ARG_VAL(value, 0)
385 PHP_HTTP_END_ARGS;
386 PHP_HTTP_BEGIN_ARGS(setExpires, 0)
387 PHP_HTTP_ARG_VAL(value, 0)
388 PHP_HTTP_END_ARGS;
389 PHP_HTTP_BEGIN_ARGS(setFlags, 0)
390 PHP_HTTP_ARG_VAL(value, 0)
391 PHP_HTTP_END_ARGS;
392
393 PHP_HTTP_BEGIN_ARGS(setCookies, 0)
394 PHP_HTTP_ARG_VAL(cookies, 0)
395 PHP_HTTP_END_ARGS;
396 PHP_HTTP_BEGIN_ARGS(addCookies, 1)
397 PHP_HTTP_ARG_VAL(cookies, 0)
398 PHP_HTTP_END_ARGS;
399 PHP_HTTP_BEGIN_ARGS(setExtras, 0)
400 PHP_HTTP_ARG_VAL(extras, 0)
401 PHP_HTTP_END_ARGS;
402 PHP_HTTP_BEGIN_ARGS(addExtras, 1)
403 PHP_HTTP_ARG_VAL(extras, 0)
404 PHP_HTTP_END_ARGS;
405 PHP_HTTP_BEGIN_ARGS(setCookie, 1)
406 PHP_HTTP_ARG_VAL(cookie_name, 0)
407 PHP_HTTP_ARG_VAL(cookie_value, 0)
408 PHP_HTTP_END_ARGS;
409 PHP_HTTP_BEGIN_ARGS(addCookie, 1)
410 PHP_HTTP_ARG_VAL(cookie_name, 0)
411 PHP_HTTP_ARG_VAL(cookie_value, 0)
412 PHP_HTTP_END_ARGS;
413 PHP_HTTP_BEGIN_ARGS(getCookie, 1)
414 PHP_HTTP_ARG_VAL(name, 0)
415 PHP_HTTP_END_ARGS;
416 PHP_HTTP_BEGIN_ARGS(setExtra, 1)
417 PHP_HTTP_ARG_VAL(extra_name, 0)
418 PHP_HTTP_ARG_VAL(extra_value, 0)
419 PHP_HTTP_END_ARGS;
420 PHP_HTTP_BEGIN_ARGS(addExtra, 1)
421 PHP_HTTP_ARG_VAL(extra_name, 0)
422 PHP_HTTP_ARG_VAL(extra_value, 0)
423 PHP_HTTP_END_ARGS;
424 PHP_HTTP_BEGIN_ARGS(getExtra, 1)
425 PHP_HTTP_ARG_VAL(name, 0)
426 PHP_HTTP_END_ARGS;
427
428 static zend_class_entry *php_http_cookie_class_entry;
429
430 zend_class_entry *php_http_cookie_get_class_entry(void)
431 {
432 return php_http_cookie_class_entry;
433 }
434
435 static zend_function_entry php_http_cookie_method_entry[] = {
436 PHP_HTTP_COOKIE_ME(__construct, ZEND_ACC_PUBLIC)
437 PHP_HTTP_COOKIE_ME(getCookies, ZEND_ACC_PUBLIC)
438 PHP_HTTP_COOKIE_ME(setCookies, ZEND_ACC_PUBLIC)
439 PHP_HTTP_COOKIE_ME(addCookies, ZEND_ACC_PUBLIC)
440 PHP_HTTP_COOKIE_ME(getCookie, ZEND_ACC_PUBLIC)
441 PHP_HTTP_COOKIE_ME(setCookie, ZEND_ACC_PUBLIC)
442 PHP_HTTP_COOKIE_ME(addCookie, ZEND_ACC_PUBLIC)
443
444 PHP_HTTP_COOKIE_ME(getExtras, ZEND_ACC_PUBLIC)
445 PHP_HTTP_COOKIE_ME(setExtras, ZEND_ACC_PUBLIC)
446 PHP_HTTP_COOKIE_ME(addExtras, ZEND_ACC_PUBLIC)
447 PHP_HTTP_COOKIE_ME(getExtra, ZEND_ACC_PUBLIC)
448 PHP_HTTP_COOKIE_ME(setExtra, ZEND_ACC_PUBLIC)
449 PHP_HTTP_COOKIE_ME(addExtra, ZEND_ACC_PUBLIC)
450
451 PHP_HTTP_COOKIE_ME(getDomain, ZEND_ACC_PUBLIC)
452 PHP_HTTP_COOKIE_ME(setDomain, ZEND_ACC_PUBLIC)
453 PHP_HTTP_COOKIE_ME(getPath, ZEND_ACC_PUBLIC)
454 PHP_HTTP_COOKIE_ME(setPath, ZEND_ACC_PUBLIC)
455 PHP_HTTP_COOKIE_ME(getExpires, ZEND_ACC_PUBLIC)
456 PHP_HTTP_COOKIE_ME(setExpires, ZEND_ACC_PUBLIC)
457 PHP_HTTP_COOKIE_ME(getFlags, ZEND_ACC_PUBLIC)
458 PHP_HTTP_COOKIE_ME(setFlags, ZEND_ACC_PUBLIC)
459
460 PHP_HTTP_COOKIE_ME(toArray, ZEND_ACC_PUBLIC)
461 PHP_HTTP_COOKIE_ME(toString, ZEND_ACC_PUBLIC)
462 ZEND_MALIAS(HttpCookie, __toString, toString, PHP_HTTP_ARGS(HttpCookie, toString), ZEND_ACC_PUBLIC)
463
464 EMPTY_FUNCTION_ENTRY
465 };
466 static zend_object_handlers php_http_cookie_object_handlers;
467
468 zend_object_value php_http_cookie_object_new(zend_class_entry *ce TSRMLS_DC)
469 {
470 return php_http_cookie_object_new_ex(ce, NULL, NULL TSRMLS_CC);
471 }
472
473 zend_object_value php_http_cookie_object_new_ex(zend_class_entry *ce, php_http_cookie_list_t *list, php_http_cookie_object_t **ptr TSRMLS_DC)
474 {
475 zend_object_value ov;
476 php_http_cookie_object_t *o;
477
478 o = ecalloc(sizeof(*o), 1);
479 zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
480 object_properties_init((zend_object *) o, ce);
481
482 if (list) {
483 o->list = list;
484 }
485
486 if (ptr) {
487 *ptr = o;
488 }
489
490 ov.handle = zend_objects_store_put(o, NULL, php_http_cookie_object_free, NULL TSRMLS_CC);
491 ov.handlers = &php_http_cookie_object_handlers;
492
493 return ov;
494 }
495
496 zend_object_value php_http_cookie_object_clone(zval *this_ptr TSRMLS_DC)
497 {
498 php_http_cookie_object_t *new_obj, *old_obj = zend_object_store_get_object(getThis() TSRMLS_CC);
499 zend_object_value ov;
500
501 if (!old_obj->list) {
502 old_obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
503 }
504 ov = php_http_cookie_object_new_ex(old_obj->o.ce, php_http_cookie_list_copy(old_obj->list, NULL), &new_obj TSRMLS_CC);
505 zend_objects_clone_members((zend_object *) new_obj, ov, (zend_object *) old_obj, Z_OBJ_HANDLE_P(getThis()) TSRMLS_CC);
506
507 return ov;
508 }
509
510 void php_http_cookie_object_free(void *object TSRMLS_DC)
511 {
512 php_http_cookie_object_t *obj = object;
513
514 php_http_cookie_list_free(&obj->list);
515 zend_object_std_dtor((zend_object *) obj TSRMLS_CC);
516 efree(obj);
517 }
518
519 PHP_METHOD(HttpCookie, __construct)
520 {
521 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
522 zval *zcookie = NULL;
523 long flags = 0;
524 HashTable *allowed_extras = NULL;
525
526 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!lH", &zcookie, &flags, &allowed_extras)) {
527 if (zcookie) {
528 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
529 char **ae = NULL;
530 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
531
532 if (allowed_extras && zend_hash_num_elements(allowed_extras)) {
533 char **ae_ptr = safe_emalloc(zend_hash_num_elements(allowed_extras) + 1, sizeof(char *), 0);
534 HashPosition pos;
535 zval **val;
536
537 ae = ae_ptr;
538 FOREACH_HASH_VAL(pos, allowed_extras, val) {
539 zval *cpy = php_http_ztyp(IS_STRING, *val);
540
541 *ae_ptr++ = estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy));
542 zval_ptr_dtor(&cpy);
543 }
544 *ae_ptr = NULL;
545 }
546
547 switch (Z_TYPE_P(zcookie)) {
548 case IS_OBJECT:
549 if (instanceof_function(Z_OBJCE_P(zcookie), php_http_cookie_class_entry TSRMLS_CC)) {
550 php_http_cookie_object_t *zco = zend_object_store_get_object(zcookie TSRMLS_CC);
551
552 if (zco->list) {
553 obj->list = php_http_cookie_list_copy(zco->list, NULL);
554 }
555 break;
556 }
557 /* no break */
558 case IS_ARRAY:
559 obj->list = php_http_cookie_list_from_struct(obj->list, zcookie TSRMLS_CC);
560 break;
561 default: {
562 zval *cpy = php_http_ztyp(IS_STRING, zcookie);
563
564 obj->list = php_http_cookie_list_parse(obj->list, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy), flags, ae TSRMLS_CC);
565 zval_ptr_dtor(&cpy);
566 break;
567 }
568 }
569 } end_error_handling();
570 }
571 }
572 } end_error_handling();
573 }
574
575 PHP_METHOD(HttpCookie, getCookies)
576 {
577 if (SUCCESS == zend_parse_parameters_none()) {
578 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
579
580 if (!obj->list) {
581 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
582 }
583 array_init(return_value);
584 array_copy(&obj->list->cookies, Z_ARRVAL_P(return_value));
585 return;
586 }
587 RETURN_FALSE;
588 }
589
590 PHP_METHOD(HttpCookie, setCookies)
591 {
592 HashTable *cookies = NULL;
593
594 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H", &cookies)) {
595 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
596
597 if (!obj->list) {
598 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
599 }
600 zend_hash_clean(&obj->list->cookies);
601 if (cookies) {
602 array_copy(cookies, &obj->list->cookies);
603 }
604 }
605 RETVAL_ZVAL(getThis(), 1, 0);
606 }
607
608 PHP_METHOD(HttpCookie, addCookies)
609 {
610 HashTable *cookies = NULL;
611
612 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &cookies)) {
613 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
614
615 if (!obj->list) {
616 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
617 }
618 array_join(cookies, &obj->list->cookies, 1, ARRAY_JOIN_STRONLY);
619 }
620 RETVAL_ZVAL(getThis(), 1, 0);
621 }
622
623
624 PHP_METHOD(HttpCookie, getExtras)
625 {
626 if (SUCCESS == zend_parse_parameters_none()) {
627 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
628
629 if (!obj->list) {
630 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
631 }
632 array_init(return_value);
633 array_copy(&obj->list->extras, Z_ARRVAL_P(return_value));
634 return;
635 }
636 RETURN_FALSE;
637 }
638
639 PHP_METHOD(HttpCookie, setExtras)
640 {
641 HashTable *extras = NULL;
642
643 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H", &extras)) {
644 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
645
646 if (!obj->list) {
647 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
648 }
649 zend_hash_clean(&obj->list->extras);
650 if (extras) {
651 array_copy(extras, &obj->list->extras);
652 }
653 }
654 RETVAL_ZVAL(getThis(), 1, 0);
655 }
656
657 PHP_METHOD(HttpCookie, addExtras)
658 {
659 HashTable *extras = NULL;
660
661 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &extras)) {
662 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
663
664 if (!obj->list) {
665 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
666 }
667 array_join(extras, &obj->list->extras, 1, ARRAY_JOIN_STRONLY);
668 }
669 RETVAL_ZVAL(getThis(), 1, 0);
670 }
671
672 PHP_METHOD(HttpCookie, getCookie)
673 {
674 char *name_str;
675 int name_len;
676
677 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) {
678 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
679 zval **zvalue;
680
681 if (!obj->list) {
682 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
683 }
684 if (SUCCESS == zend_symtable_find(&obj->list->cookies, name_str, name_len + 1, (void *) &zvalue)) {
685 RETURN_ZVAL(*zvalue, 1, 0);
686 }
687 }
688 RETURN_FALSE;
689 }
690
691 PHP_METHOD(HttpCookie, setCookie)
692 {
693 char *name_str, *value_str = NULL;
694 int name_len, value_len = 0;
695
696 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &name_str, &name_len, &value_str, &value_len)) {
697 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
698
699 if (!obj->list) {
700 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
701 }
702 if (!value_str) {
703 zend_symtable_del(&obj->list->cookies, name_str, name_len + 1);
704 } else {
705 zval *zvalue;
706
707 MAKE_STD_ZVAL(zvalue);
708 ZVAL_STRINGL(zvalue, value_str, value_len, 1);
709 zend_symtable_update(&obj->list->cookies, name_str, name_len + 1, &zvalue, sizeof(zval *), NULL);
710 }
711 }
712 RETVAL_ZVAL(getThis(), 1, 0);
713 }
714
715 PHP_METHOD(HttpCookie, addCookie)
716 {
717 char *name_str, *value_str;
718 int name_len, value_len;
719
720 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name_str, &name_len, &value_str, &value_len)) {
721 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
722 zval *zvalue;
723
724 if (!obj->list) {
725 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
726 }
727 MAKE_STD_ZVAL(zvalue);
728 ZVAL_STRINGL(zvalue, value_str, value_len, 1);
729 zend_symtable_update(&obj->list->cookies, name_str, name_len + 1, &zvalue, sizeof(zval *), NULL);
730 }
731 RETVAL_ZVAL(getThis(), 1, 0);
732 }
733
734 PHP_METHOD(HttpCookie, getExtra)
735 {
736 char *name_str;
737 int name_len;
738
739 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len)) {
740 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
741 zval **zvalue;
742
743 if (!obj->list) {
744 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
745 }
746 if (SUCCESS == zend_symtable_find(&obj->list->extras, name_str, name_len + 1, (void *) &zvalue)) {
747 RETURN_ZVAL(*zvalue, 1, 0);
748 }
749 }
750 RETURN_FALSE;
751 }
752
753 PHP_METHOD(HttpCookie, setExtra)
754 {
755 char *name_str, *value_str = NULL;
756 int name_len, value_len = 0;
757
758 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &name_str, &name_len, &value_str, &value_len)) {
759 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
760
761 if (!obj->list) {
762 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
763 }
764 if (!value_str) {
765 zend_symtable_del(&obj->list->extras, name_str, name_len + 1);
766 } else {
767 zval *zvalue;
768
769 MAKE_STD_ZVAL(zvalue);
770 ZVAL_STRINGL(zvalue, value_str, value_len, 1);
771 zend_symtable_update(&obj->list->extras, name_str, name_len + 1, &zvalue, sizeof(zval *), NULL);
772 }
773 }
774 RETVAL_ZVAL(getThis(), 1, 0);
775 }
776
777 PHP_METHOD(HttpCookie, addExtra)
778 {
779 char *name_str, *value_str;
780 int name_len, value_len;
781
782 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name_str, &name_len, &value_str, &value_len)) {
783 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
784 zval *zvalue;
785
786 if (!obj->list) {
787 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
788 }
789 MAKE_STD_ZVAL(zvalue);
790 ZVAL_STRINGL(zvalue, value_str, value_len, 1);
791 zend_symtable_update(&obj->list->extras, name_str, name_len + 1, &zvalue, sizeof(zval *), NULL);
792 }
793 RETVAL_ZVAL(getThis(), 1, 0);
794 }
795
796 PHP_METHOD(HttpCookie, getDomain)
797 {
798 if (SUCCESS == zend_parse_parameters_none()) {
799 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
800
801 if (!obj->list) {
802 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
803 }
804 if (obj->list->domain) {
805 RETURN_STRING(obj->list->domain, 1);
806 }
807 RETURN_NULL();
808 }
809 RETURN_FALSE;
810 }
811
812 PHP_METHOD(HttpCookie, setDomain)
813 {
814 char *domain_str = NULL;
815 int domain_len = 0;
816
817 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &domain_str, &domain_len)) {
818 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
819
820 if (!obj->list) {
821 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
822 }
823 STR_SET(obj->list->domain, domain_str ? estrndup(domain_str, domain_len) : NULL);
824 }
825 RETVAL_ZVAL(getThis(), 1, 0);
826 }
827
828 PHP_METHOD(HttpCookie, getPath)
829 {
830 if (SUCCESS == zend_parse_parameters_none()) {
831 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
832
833 if (!obj->list) {
834 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
835 }
836 if (obj->list->path) {
837 RETURN_STRING(obj->list->path, 1);
838 }
839 RETURN_NULL();
840 }
841 RETURN_FALSE;
842 }
843
844 PHP_METHOD(HttpCookie, setPath)
845 {
846 char *path_str = NULL;
847 int path_len = 0;
848
849 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &path_str, &path_len)) {
850 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
851
852 if (!obj->list) {
853 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
854 }
855 STR_SET(obj->list->path, path_str ? estrndup(path_str, path_len) : NULL);
856 }
857 RETVAL_ZVAL(getThis(), 1, 0);
858 }
859
860 PHP_METHOD(HttpCookie, getExpires)
861 {
862 if (SUCCESS == zend_parse_parameters_none()) {
863 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
864
865 if (!obj->list) {
866 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
867 }
868 RETURN_LONG(obj->list->expires);
869 }
870 RETURN_FALSE;
871 }
872
873 PHP_METHOD(HttpCookie, setExpires)
874 {
875 long ts = -1;
876
877 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &ts)) {
878 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
879
880 if (!obj->list) {
881 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
882 }
883 obj->list->expires = ts;
884 }
885 RETVAL_ZVAL(getThis(), 1, 0);
886 }
887
888 PHP_METHOD(HttpCookie, getFlags)
889 {
890 if (SUCCESS == zend_parse_parameters_none()) {
891 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
892
893 if (!obj->list) {
894 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
895 }
896 RETURN_LONG(obj->list->flags);
897 }
898 RETURN_FALSE;
899 }
900
901 PHP_METHOD(HttpCookie, setFlags)
902 {
903 long flags = 0;
904
905 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags)) {
906 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
907
908 if (!obj->list) {
909 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
910 }
911 obj->list->flags = flags;
912 }
913 RETVAL_ZVAL(getThis(), 1, 0);
914 }
915
916 PHP_METHOD(HttpCookie, toString)
917 {
918 if (SUCCESS == zend_parse_parameters_none()) {
919 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
920 char *str;
921 size_t len;
922
923 if (!obj->list) {
924 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
925 }
926 php_http_cookie_list_to_string(obj->list, &str, &len);
927 RETURN_STRINGL(str, len, 0);
928 }
929 RETURN_EMPTY_STRING();
930 }
931
932 PHP_METHOD(HttpCookie, toArray)
933 {
934 if (SUCCESS == zend_parse_parameters_none()) {
935 php_http_cookie_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
936
937 if (!obj->list) {
938 obj->list = php_http_cookie_list_init(NULL TSRMLS_CC);
939 }
940 array_init(return_value);
941 php_http_cookie_list_to_struct(obj->list, return_value);
942 }
943 }
944
945 PHP_MINIT_FUNCTION(http_cookie)
946 {
947 PHP_HTTP_REGISTER_CLASS(http, Cookie, http_cookie, php_http_object_get_class_entry(), 0);
948 php_http_cookie_class_entry->create_object = php_http_cookie_object_new;
949 memcpy(&php_http_cookie_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
950 php_http_cookie_object_handlers.clone_obj = php_http_cookie_object_clone;
951
952 zend_declare_class_constant_long(php_http_cookie_class_entry, ZEND_STRL("PARSE_RAW"), PHP_HTTP_COOKIE_PARSE_RAW TSRMLS_CC);
953 zend_declare_class_constant_long(php_http_cookie_class_entry, ZEND_STRL("SECURE"), PHP_HTTP_COOKIE_SECURE TSRMLS_CC);
954 zend_declare_class_constant_long(php_http_cookie_class_entry, ZEND_STRL("HTTPONLY"), PHP_HTTP_COOKIE_HTTPONLY TSRMLS_CC);
955
956 return SUCCESS;
957 }
958
959
960
961 /*
962 * Local variables:
963 * tab-width: 4
964 * c-basic-offset: 4
965 * End:
966 * vim600: noet sw=4 ts=4 fdm=marker
967 * vim<600: noet sw=4 ts=4
968 */