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