2 +--------------------------------------------------------------------+
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 +--------------------------------------------------------------------+
16 #include "php_http_api.h"
17 #include "php_http_date_api.h"
18 #include "php_http_cookie_api.h"
20 PHP_MINIT_FUNCTION(http_cookie
)
22 HTTP_LONG_CONSTANT("HTTP_COOKIE_PARSE_RAW", HTTP_COOKIE_PARSE_RAW
);
23 HTTP_LONG_CONSTANT("HTTP_COOKIE_SECURE", HTTP_COOKIE_SECURE
);
24 HTTP_LONG_CONSTANT("HTTP_COOKIE_HTTPONLY", HTTP_COOKIE_HTTPONLY
);
29 PHP_HTTP_API http_cookie_list
*_http_cookie_list_init(http_cookie_list
*list ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC
)
32 list
= emalloc_rel(sizeof(http_cookie_list
));
35 zend_hash_init(&list
->cookies
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
36 zend_hash_init(&list
->extras
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
46 PHP_HTTP_API
void _http_cookie_list_dtor(http_cookie_list
*list TSRMLS_DC
)
49 zend_hash_destroy(&list
->cookies
);
50 zend_hash_destroy(&list
->extras
);
52 STR_SET(list
->path
, NULL
);
53 STR_SET(list
->domain
, NULL
);
57 PHP_HTTP_API
void _http_cookie_list_free(http_cookie_list
**list TSRMLS_DC
)
60 http_cookie_list_dtor(*list
);
66 PHP_HTTP_API
const char *_http_cookie_list_get_cookie(http_cookie_list
*list
, const char *name
, size_t name_len TSRMLS_DC
)
69 if ((SUCCESS
!= zend_hash_find(&list
->cookies
, (char *) name
, name_len
+ 1, (void *) &cookie
)) || (Z_TYPE_PP(cookie
) != IS_STRING
)) {
72 return Z_STRVAL_PP(cookie
);
75 PHP_HTTP_API
const char *_http_cookie_list_get_extra(http_cookie_list
*list
, const char *name
, size_t name_len TSRMLS_DC
)
78 if ((SUCCESS
!= zend_hash_find(&list
->extras
, (char *) name
, name_len
+ 1, (void *) &extra
)) || (Z_TYPE_PP(extra
) != IS_STRING
)) {
81 return Z_STRVAL_PP(extra
);
84 PHP_HTTP_API
void _http_cookie_list_add_cookie(http_cookie_list
*list
, const char *name
, size_t name_len
, const char *value
, size_t value_len TSRMLS_DC
)
87 MAKE_STD_ZVAL(cookie_value
);
88 ZVAL_STRINGL(cookie_value
, estrndup(value
, value_len
), value_len
, 0);
89 zend_hash_update(&list
->cookies
, (char *) name
, name_len
+ 1, (void *) &cookie_value
, sizeof(zval
*), NULL
);
92 PHP_HTTP_API
void _http_cookie_list_add_extra(http_cookie_list
*list
, const char *name
, size_t name_len
, const char *value
, size_t value_len TSRMLS_DC
)
95 MAKE_STD_ZVAL(cookie_value
);
96 ZVAL_STRINGL(cookie_value
, estrndup(value
, value_len
), value_len
, 0);
97 zend_hash_update(&list
->extras
, (char *) name
, name_len
+ 1, (void *) &cookie_value
, sizeof(zval
*), NULL
);
100 #define http_cookie_list_set_item_ex(l, i, il, v, vl, f, a) _http_cookie_list_set_item_ex((l), (i), (il), (v), (vl), (f), (a) TSRMLS_CC)
101 static inline void _http_cookie_list_set_item_ex(http_cookie_list
*list
, const char *item
, int item_len
, const char *value
, int value_len
, long flags
, char **allowed_extras TSRMLS_DC
)
103 char *key
= estrndup(item
, item_len
);
105 if (!strcasecmp(key
, "path")) {
106 STR_SET(list
->path
, estrndup(value
, value_len
));
107 } else if (!strcasecmp(key
, "domain")) {
108 STR_SET(list
->domain
, estrndup(value
, value_len
));
109 } else if (!strcasecmp(key
, "expires")) {
110 char *date
= estrndup(value
, value_len
);
111 list
->expires
= http_parse_date(date
);
113 } else if (!strcasecmp(key
, "secure")) {
114 list
->flags
|= HTTP_COOKIE_SECURE
;
115 } else if (!strcasecmp(key
, "httpOnly")) {
116 list
->flags
|= HTTP_COOKIE_HTTPONLY
;
118 /* check for extra */
119 if (allowed_extras
) {
120 for (; *allowed_extras
; ++allowed_extras
) {
121 if (!strcasecmp(key
, *allowed_extras
)) {
122 http_cookie_list_add_extra(list
, key
, item_len
, value
, value_len
);
130 http_cookie_list_add_cookie(list
, key
, item_len
, value
, value_len
);
142 /* {{{ http_cookie_list *http_parse_cookie(char *, long) */
143 PHP_HTTP_API http_cookie_list
*_http_parse_cookie_ex(http_cookie_list
*list
, const char *string
, long flags
, char **allowed_extras TSRMLS_DC
)
145 int free_list
= !list
, st
= ST_KEY
, keylen
= 0, vallen
= 0;
146 char *s
, *c
, *key
= NULL
, *val
= NULL
;
148 list
= http_cookie_list_init(list
);
150 c
= s
= estrdup(string
);
153 char *tk
= NULL
, *tv
= NULL
;
157 tk
= estrndup(key
, keylen
);
161 tk
[3]='.'; tk
[4]='.'; tk
[5]='.';
166 tv
= estrndup(val
, vallen
);
170 tv
[3]='.'; tv
[4]='.'; tv
[5]='.';
173 fprintf(stderr
, "[%6s] %c \"%s=%s\"\n",
175 st
== ST_QUOTE
? "QUOTE" :
176 st
== ST_VALUE
? "VALUE" :
177 st
== ST_KEY
? "KEY" :
178 st
== ST_ASSIGN
? "ASSIGN" :
179 st
== ST_ADD
? "ADD":
183 STR_FREE(tk
); STR_FREE(tv
);
190 if (*(c
-1) == '\\') {
191 memmove(c
-1, c
, strlen(c
)+1);
279 } else if (!*c
|| *c
== ';') {
281 } else if (*c
!= ' ') {
290 if (st
!= ST_QUOTE
) {
291 while (val
[vallen
-1] == ' ') --vallen
;
297 http_cookie_list_set_item_ex(list
, key
, keylen
, val
, vallen
, flags
, allowed_extras
);
306 } else if (st
== ST_ADD
) {
317 http_error_ex(HE_WARNING
, HTTP_E_INVALID_PARAM
, "Unexpected character (%c) at pos %tu of %zu", *c
, c
-s
, strlen(s
));
319 http_cookie_list_free(&list
);
321 http_cookie_list_dtor(list
);
328 PHP_HTTP_API
void _http_cookie_list_tostruct(http_cookie_list
*list
, zval
*strct TSRMLS_DC
)
330 zval array
, *cookies
, *extras
;
332 INIT_ZARR(array
, HASH_OF(strct
));
334 MAKE_STD_ZVAL(cookies
);
336 zend_hash_copy(Z_ARRVAL_P(cookies
), &list
->cookies
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
337 add_assoc_zval(&array
, "cookies", cookies
);
339 MAKE_STD_ZVAL(extras
);
341 zend_hash_copy(Z_ARRVAL_P(extras
), &list
->extras
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
342 add_assoc_zval(&array
, "extras", extras
);
344 add_assoc_long(&array
, "flags", list
->flags
);
345 add_assoc_long(&array
, "expires", (long) list
->expires
);
346 add_assoc_string(&array
, "path", list
->path
?list
->path
:"", 1);
347 add_assoc_string(&array
, "domain", list
->domain
?list
->domain
:"", 1);
355 * vim600: noet sw=4 ts=4 fdm=marker
356 * vim<600: noet sw=4 ts=4