LTP GCOV extension - code coverage report
Current view: directory - ext/http - http_cookie_api.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 179
Code covered: 48.0 % Executed lines: 86
Legend: not executed executed

       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-2007, Michael Wallner <mike@php.net>            |
      10                 :     +--------------------------------------------------------------------+
      11                 : */
      12                 : 
      13                 : /* $Id: http_cookie_api.c,v 1.13 2007/02/10 08:41:38 mike Exp $ */
      14                 : 
      15                 : #include "php_http.h"
      16                 : #include "php_http_api.h"
      17                 : #include "php_http_date_api.h"
      18                 : #include "php_http_cookie_api.h"
      19                 : 
      20                 : #include "ext/standard/url.h"
      21                 : 
      22                 : /* {{{ PHP_MINIT_FUNCTION(http_cookie) */
      23                 : PHP_MINIT_FUNCTION(http_cookie)
      24             220 : {
      25             220 :         HTTP_LONG_CONSTANT("HTTP_COOKIE_PARSE_RAW", HTTP_COOKIE_PARSE_RAW);
      26             220 :         HTTP_LONG_CONSTANT("HTTP_COOKIE_SECURE", HTTP_COOKIE_SECURE);
      27             220 :         HTTP_LONG_CONSTANT("HTTP_COOKIE_HTTPONLY", HTTP_COOKIE_HTTPONLY);
      28                 :         
      29             220 :         return SUCCESS;
      30                 : }
      31                 : /* }}} */
      32                 : 
      33                 : /* {{{ http_cookie_list *http_cookie_list_init(http_cookie_list *) */
      34                 : 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)
      35              35 : {
      36              35 :         if (!list) {
      37               0 :                 list = emalloc_rel(sizeof(http_cookie_list));
      38                 :         }
      39                 :         
      40              35 :         zend_hash_init(&list->cookies, 0, NULL, ZVAL_PTR_DTOR, 0);
      41              35 :         zend_hash_init(&list->extras, 0, NULL, ZVAL_PTR_DTOR, 0);
      42                 :         
      43              35 :         list->path = NULL;
      44              35 :         list->domain = NULL;
      45              35 :         list->expires = 0;
      46              35 :         list->flags = 0;
      47                 :         
      48              35 :         return list;
      49                 : }
      50                 : /* }}} */
      51                 : 
      52                 : /* {{{ void http_cookie_list_dtor(http_cookie_list *) */
      53                 : PHP_HTTP_API void _http_cookie_list_dtor(http_cookie_list *list TSRMLS_DC)
      54              35 : {
      55              35 :         if (list) {
      56              35 :                 zend_hash_destroy(&list->cookies);
      57              35 :                 zend_hash_destroy(&list->extras);
      58                 :         
      59              35 :                 STR_SET(list->path, NULL);
      60              35 :                 STR_SET(list->domain, NULL);
      61                 :         }
      62              35 : }
      63                 : /* }}} */
      64                 : 
      65                 : /* {{{ void http_cookie_list_free(http_cookie_list **) */
      66                 : PHP_HTTP_API void _http_cookie_list_free(http_cookie_list **list TSRMLS_DC)
      67               0 : {
      68               0 :         if (list) {
      69               0 :                 http_cookie_list_dtor(*list);
      70               0 :                 efree(*list);
      71               0 :                 *list = NULL;
      72                 :         }
      73               0 : }
      74                 : /* }}} */
      75                 : 
      76                 : /* {{{ const char *http_cookie_list_get_cookie(http_cookie_list *, const char*, size_t) */
      77                 : PHP_HTTP_API const char *_http_cookie_list_get_cookie(http_cookie_list *list, const char *name, size_t name_len TSRMLS_DC)
      78               0 : {
      79               0 :         zval **cookie = NULL;
      80               0 :         if ((SUCCESS != zend_hash_find(&list->cookies, (char *) name, name_len + 1, (void *) &cookie)) || (Z_TYPE_PP(cookie) != IS_STRING)) {
      81               0 :                 return NULL;
      82                 :         }
      83               0 :         return Z_STRVAL_PP(cookie);
      84                 : }
      85                 : /* }}} */
      86                 : 
      87                 : /* {{{ const char *http_cookie_list_get_extra(http_cookie_list *, const char *, size_t) */
      88                 : PHP_HTTP_API const char *_http_cookie_list_get_extra(http_cookie_list *list, const char *name, size_t name_len TSRMLS_DC)
      89               0 : {
      90               0 :         zval **extra = NULL;
      91               0 :         if ((SUCCESS != zend_hash_find(&list->extras, (char *) name, name_len + 1, (void *) &extra)) || (Z_TYPE_PP(extra) != IS_STRING)) {
      92               0 :                 return NULL;
      93                 :         }
      94               0 :         return Z_STRVAL_PP(extra);
      95                 : }
      96                 : /* }}} */
      97                 : 
      98                 : /* {{{ void http_cookie_list_add_cookie(http_cookie_list *, const char *, size_t, const char *, size_t) */
      99                 : 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)
     100              37 : {
     101                 :         zval *cookie_value;
     102              37 :         char *key = estrndup(name, name_len);
     103              37 :         MAKE_STD_ZVAL(cookie_value);
     104              37 :         ZVAL_STRINGL(cookie_value, estrndup(value, value_len), value_len, 0);
     105              37 :         zend_hash_update(&list->cookies, key, name_len + 1, (void *) &cookie_value, sizeof(zval *), NULL);
     106              37 :         efree(key);
     107              37 : }
     108                 : /* }}} */
     109                 : 
     110                 : /* {{{ void http_cookie_list_add_extr(http_cookie_list *, const char *, size_t, const char *, size_t) */
     111                 : 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)
     112               1 : {
     113                 :         zval *cookie_value;
     114               1 :         char *key = estrndup(name, name_len);
     115               1 :         MAKE_STD_ZVAL(cookie_value);
     116               1 :         ZVAL_STRINGL(cookie_value, estrndup(value, value_len), value_len, 0);
     117               1 :         zend_hash_update(&list->extras, key, name_len + 1, (void *) &cookie_value, sizeof(zval *), NULL);
     118               1 :         efree(key);
     119               1 : }
     120                 : /* }}} */
     121                 : 
     122                 : typedef struct _http_parse_param_cb_arg_t {
     123                 :         http_cookie_list *list;
     124                 :         long flags;
     125                 :         char **allowed_extras;
     126                 : } http_parse_param_cb_arg;
     127                 : 
     128                 : /* {{{ static void http_parse_cookie_callback */
     129                 : static void http_parse_cookie_callback(void *ptr, const char *key, int keylen, const char *val, int vallen TSRMLS_DC)
     130              47 : {
     131              47 :         http_parse_param_cb_arg *arg = (http_parse_param_cb_arg *) ptr;
     132                 :         
     133                 : #define _KEY_IS(s) (keylen == lenof(s) && !strncasecmp(key, (s), keylen))
     134              50 :         if _KEY_IS("path") {
     135               3 :                 STR_SET(arg->list->path, estrndup(val, vallen));
     136              46 :         } else if _KEY_IS("domain") {
     137               2 :                 STR_SET(arg->list->domain, estrndup(val, vallen));
     138              45 :         } else if _KEY_IS("expires") {
     139               3 :                 char *date = estrndup(val, vallen);
     140               3 :                 arg->list->expires = http_parse_date(date);
     141               3 :                 efree(date);
     142              39 :         } else if _KEY_IS("secure") {
     143               0 :                 arg->list->flags |= HTTP_COOKIE_SECURE;
     144              40 :         } else if _KEY_IS("httpOnly") {
     145               1 :                 arg->list->flags |= HTTP_COOKIE_HTTPONLY;
     146                 :         } else {
     147                 :                 /* check for extra */
     148              38 :                 if (arg->allowed_extras) {
     149               4 :                         char **ae = arg->allowed_extras;
     150                 :                         
     151               7 :                         for (; *ae; ++ae) {
     152               4 :                                 if ((size_t) keylen == strlen(*ae) && !strncasecmp(key, *ae, keylen)) {
     153               1 :                                         if (arg->flags & HTTP_COOKIE_PARSE_RAW) {
     154               0 :                                                 http_cookie_list_add_extra(arg->list, key, keylen, val, vallen);
     155                 :                                         } else {
     156               1 :                                                 char *dec = estrndup(val, vallen);
     157               1 :                                                 int declen = php_url_decode(dec, vallen);
     158                 :                                                 
     159               1 :                                                 http_cookie_list_add_extra(arg->list, key, keylen, dec, declen);
     160               1 :                                                 efree(dec);
     161                 :                                         }
     162               1 :                                         return;
     163                 :                                 }
     164                 :                         }
     165                 :                 }
     166                 :                 /* new cookie */
     167              37 :                 if (arg->flags & HTTP_COOKIE_PARSE_RAW) {
     168               0 :                         http_cookie_list_add_cookie(arg->list, key, keylen, val, vallen);
     169                 :                 } else {
     170              37 :                         char *dec = estrndup(val, vallen);
     171              37 :                         int declen = php_url_decode(dec, vallen);
     172                 :                         
     173              37 :                         http_cookie_list_add_cookie(arg->list, key, keylen, dec, declen);
     174              37 :                         efree(dec);
     175                 :                 }
     176                 :         }
     177                 : }
     178                 : /* }}} */
     179                 : 
     180                 : /* {{{ http_cookie_list *http_parse_cookie(char *, long) */
     181                 : PHP_HTTP_API http_cookie_list *_http_parse_cookie_ex(http_cookie_list *list, const char *string, long flags, char **allowed_extras TSRMLS_DC)
     182              35 : {
     183              35 :         int free_list = !list;
     184                 :         http_parse_param_cb_arg arg;
     185                 :         
     186              35 :         list = http_cookie_list_init(list);
     187                 :         
     188              35 :         arg.list = list;
     189              35 :         arg.flags = flags;
     190              35 :         arg.allowed_extras = allowed_extras;
     191                 :         
     192              35 :         if (SUCCESS != http_parse_params_ex(string, HTTP_PARAMS_RAISE_ERROR, http_parse_cookie_callback, &arg)) {
     193               0 :                 if (free_list) {
     194               0 :                         http_cookie_list_free(&list);
     195                 :                 } else {
     196               0 :                         http_cookie_list_dtor(list);
     197                 :                 }
     198               0 :                 list = NULL;
     199                 :         }
     200                 :         
     201              35 :         return list;
     202                 : }
     203                 : /* }}} */
     204                 : 
     205                 : /* {{{ void http_cookie_list_tostruct(http_cookie_list *, zval *) */
     206                 : PHP_HTTP_API void _http_cookie_list_tostruct(http_cookie_list *list, zval *strct TSRMLS_DC)
     207              35 : {
     208                 :         zval array, *cookies, *extras;
     209                 :         
     210              35 :         INIT_ZARR(array, HASH_OF(strct));
     211                 :         
     212              35 :         MAKE_STD_ZVAL(cookies);
     213              35 :         array_init(cookies);
     214              35 :         zend_hash_copy(Z_ARRVAL_P(cookies), &list->cookies, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
     215              35 :         add_assoc_zval(&array, "cookies", cookies);
     216                 :         
     217              35 :         MAKE_STD_ZVAL(extras);
     218              35 :         array_init(extras);
     219              35 :         zend_hash_copy(Z_ARRVAL_P(extras), &list->extras, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
     220              35 :         add_assoc_zval(&array, "extras", extras);
     221                 :         
     222              35 :         add_assoc_long(&array, "flags", list->flags);
     223              35 :         add_assoc_long(&array, "expires", (long) list->expires);
     224              35 :         add_assoc_string(&array, "path", STR_PTR(list->path), 1);
     225              35 :         add_assoc_string(&array, "domain", STR_PTR(list->domain), 1);
     226              35 : }
     227                 : /* }}} */
     228                 : 
     229                 : /* {{{ http_cookie_list *http_cookie_list_fromstruct(http_cookie_list *, zval *strct) */
     230                 : PHP_HTTP_API http_cookie_list *_http_cookie_list_fromstruct(http_cookie_list *list, zval *strct TSRMLS_DC)
     231               0 : {
     232                 :         zval **tmp, *cpy;
     233               0 :         HashTable *ht = HASH_OF(strct);
     234                 :         
     235               0 :         list = http_cookie_list_init(list);
     236                 :         
     237               0 :         if (SUCCESS == zend_hash_find(ht, "cookies", sizeof("cookies"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_ARRAY) {
     238               0 :                 zend_hash_copy(&list->cookies, Z_ARRVAL_PP(tmp), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
     239                 :         }
     240               0 :         if (SUCCESS == zend_hash_find(ht, "extras", sizeof("extras"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_ARRAY) {
     241               0 :                 zend_hash_copy(&list->extras, Z_ARRVAL_PP(tmp), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
     242                 :         }
     243               0 :         if (SUCCESS == zend_hash_find(ht, "flags", sizeof("flags"), (void *) &tmp)) {
     244               0 :                 switch (Z_TYPE_PP(tmp)) {
     245                 :                         case IS_LONG:
     246               0 :                                 list->flags = Z_LVAL_PP(tmp);
     247               0 :                                 break;
     248                 :                         case IS_DOUBLE:
     249               0 :                                 list->flags = (long) Z_DVAL_PP(tmp);
     250               0 :                                 break;
     251                 :                         case IS_STRING:
     252               0 :                                 cpy = zval_copy(IS_LONG, *tmp);
     253               0 :                                 list->flags = Z_LVAL_P(cpy);
     254               0 :                                 zval_free(&cpy);
     255                 :                                 break;
     256                 :                         default:
     257                 :                                 break;
     258                 :                 }
     259                 :         }
     260               0 :         if (SUCCESS == zend_hash_find(ht, "expires", sizeof("expires"), (void *) &tmp)) {
     261               0 :                 switch (Z_TYPE_PP(tmp)) {
     262                 :                         case IS_LONG:
     263               0 :                                 list->expires = Z_LVAL_PP(tmp);
     264               0 :                                 break;
     265                 :                         case IS_DOUBLE:
     266               0 :                                 list->expires = (long) Z_DVAL_PP(tmp);
     267               0 :                                 break;
     268                 :                         case IS_STRING:
     269               0 :                                 cpy = zval_copy(IS_LONG, *tmp);
     270               0 :                                 if (Z_LVAL_P(cpy)) {
     271               0 :                                         list->expires = Z_LVAL_P(cpy);
     272                 :                                 } else {
     273               0 :                                         time_t expires = http_parse_date(Z_STRVAL_PP(tmp));
     274               0 :                                         if (expires > 0) {
     275               0 :                                                 list->expires = expires;
     276                 :                                         }
     277                 :                                 }
     278               0 :                                 zval_free(&cpy);
     279                 :                                 break;
     280                 :                         default:
     281                 :                                 break;
     282                 :                 }
     283                 :         }
     284               0 :         if (SUCCESS == zend_hash_find(ht, "path", sizeof("path"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_STRING) {
     285               0 :                 list->path = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     286                 :         }
     287               0 :         if (SUCCESS == zend_hash_find(ht, "domain", sizeof("domain"), (void *) &tmp) && Z_TYPE_PP(tmp) == IS_STRING) {
     288               0 :                 list->domain = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
     289                 :         }
     290                 :         
     291               0 :         return list;
     292                 : }
     293                 : /* }}} */
     294                 : 
     295                 : /* {{{ inline append_encoded */
     296                 : static inline void append_encoded(phpstr *buf, const char *key, size_t key_len, const char *val, size_t val_len)
     297               0 : {
     298                 :         char *enc_str[2];
     299                 :         int enc_len[2];
     300                 :         
     301               0 :         enc_str[0] = php_url_encode(key, key_len, &enc_len[0]);
     302               0 :         enc_str[1] = php_url_encode(val, val_len, &enc_len[1]);
     303                 :         
     304               0 :         phpstr_append(buf, enc_str[0], enc_len[0]);
     305               0 :         phpstr_appends(buf, "=");
     306               0 :         phpstr_append(buf, enc_str[1], enc_len[1]);
     307               0 :         phpstr_appends(buf, "; ");
     308                 :         
     309               0 :         efree(enc_str[0]);
     310               0 :         efree(enc_str[1]);
     311               0 : }
     312                 : /* }}} */
     313                 : 
     314                 : /* {{{ void http_cookie_list_tostring(http_cookie_list *, char **, size_t *) */
     315                 : PHP_HTTP_API void _http_cookie_list_tostring(http_cookie_list *list, char **str, size_t *len TSRMLS_DC)
     316               0 : {
     317                 :         phpstr buf;
     318                 :         zval **val;
     319               0 :         HashKey key = initHashKey(0);
     320                 :         HashPosition pos;
     321                 :         
     322               0 :         phpstr_init(&buf);
     323                 :         
     324               0 :         FOREACH_HASH_KEYVAL(pos, &list->cookies, key, val) {
     325               0 :                 if (key.type == HASH_KEY_IS_STRING && key.len) {
     326               0 :                         append_encoded(&buf, key.str, key.len-1, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
     327                 :                 }
     328                 :         }
     329                 :         
     330               0 :         if (list->domain && *list->domain) {
     331               0 :                 phpstr_appendf(&buf, "domain=%s; ", list->domain);
     332                 :         }
     333               0 :         if (list->path && *list->path) {
     334               0 :                 phpstr_appendf(&buf, "path=%s; ", list->path);
     335                 :         }
     336               0 :         if (list->expires) {
     337               0 :                 char *date = http_date(list->expires);
     338               0 :                 phpstr_appendf(&buf, "expires=%s; ", date);
     339               0 :                 efree(date);
     340                 :         }
     341                 :         
     342               0 :         FOREACH_HASH_KEYVAL(pos, &list->extras, key, val) {
     343               0 :                 if (key.type == HASH_KEY_IS_STRING && key.len) {
     344               0 :                         append_encoded(&buf, key.str, key.len-1, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
     345                 :                 }
     346                 :         }
     347                 :         
     348               0 :         if (list->flags & HTTP_COOKIE_SECURE) {
     349               0 :                 phpstr_appends(&buf, "secure; ");
     350                 :         }
     351               0 :         if (list->flags & HTTP_COOKIE_HTTPONLY) {
     352               0 :                 phpstr_appends(&buf, "httpOnly; ");
     353                 :         }
     354                 :         
     355               0 :         phpstr_fix(&buf);
     356               0 :         *str = PHPSTR_VAL(&buf);
     357               0 :         *len = PHPSTR_LEN(&buf);
     358               0 : }
     359                 : /* }}} */
     360                 : 
     361                 : /*
     362                 :  * Local variables:
     363                 :  * tab-width: 4
     364                 :  * c-basic-offset: 4
     365                 :  * End:
     366                 :  * vim600: noet sw=4 ts=4 fdm=marker
     367                 :  * vim<600: noet sw=4 ts=4
     368                 :  */

Generated by: LTP GCOV extension version 1.5