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