Permalink
Browse files

Bug #23955: allow specifiy max age for setcookie()

  • Loading branch information...
1 parent f3824ad commit ec2fff80e768dfb04aa393c06a2b1a42a9e871ff @lstrojny lstrojny committed Jan 6, 2013
Showing with 87 additions and 7 deletions.
  1. +1 −0 NEWS
  2. +4 −0 ext/session/session.c
  3. +12 −7 ext/standard/head.c
  4. +70 −0 ext/standard/tests/network/setcookie.phpt
View
1 NEWS
@@ -7,6 +7,7 @@ PHP NEWS
. Fixed bug #63822 (Crash when using closures with ArrayAccess).
(Nikita Popov)
. Add Generator::throw() method. (Nikita Popov)
+ . Bug #23955: allow specifying Max-Age attribute in setcookie() (narfbg, Lars)
- cURL:
. Added new functions curl_escape, curl_multi_setopt, curl_multi_strerror
View
4 ext/session/session.c
@@ -1154,6 +1154,7 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
#define COOKIE_SET_COOKIE "Set-Cookie: "
#define COOKIE_EXPIRES "; expires="
+#define COOKIE_MAX_AGE "; Max-Age="
#define COOKIE_PATH "; path="
#define COOKIE_DOMAIN "; domain="
#define COOKIE_SECURE "; secure"
@@ -1201,6 +1202,9 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */
smart_str_appends(&ncookie, COOKIE_EXPIRES);
smart_str_appends(&ncookie, date_fmt);
efree(date_fmt);
+
+ smart_str_appends(&ncookie, COOKIE_MAX_AGE);
+ smart_str_append_long(&ncookie, PS(cookie_lifetime));
}
}
View
19 ext/standard/head.c
@@ -40,11 +40,11 @@ PHP_FUNCTION(header)
{
zend_bool rep = 1;
sapi_header_line ctr = {0};
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
&ctr.line_len, &rep, &ctr.response_code) == FAILURE)
return;
-
+
sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
}
/* }}} */
@@ -80,7 +80,7 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
char *dt;
sapi_header_line ctr = {0};
int result;
-
+
if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" );
return FAILURE;
@@ -111,18 +111,19 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
cookie = emalloc(len + 100);
if (value && value_len == 0) {
- /*
+ /*
* MSIE doesn't delete a cookie when you set it to a null value
* so in order to force cookies to be deleted, even on MSIE, we
* pick an expiry date in the past
*/
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC);
- snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt);
+ snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s; Max-Age=0", name, dt);
efree(dt);
} else {
snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
if (expires > 0) {
const char *p;
+ char tsdelta[13];
strlcat(cookie, "; expires=", len + 100);
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC);
/* check to make sure that the year does not exceed 4 digits in length */
@@ -136,6 +137,10 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
}
strlcat(cookie, dt, len + 100);
efree(dt);
+
+ snprintf(tsdelta, sizeof(tsdelta), "%li", (long) difftime(expires, time(NULL)));
+ strlcat(cookie, "; Max-Age=", len + 100);
+ strlcat(cookie, tsdelta, len + 100);
}
}
@@ -237,11 +242,11 @@ PHP_FUNCTION(headers_sent)
ZVAL_LONG(arg2, line);
case 1:
zval_dtor(arg1);
- if (file) {
+ if (file) {
ZVAL_STRING(arg1, file, 1);
} else {
ZVAL_STRING(arg1, "", 1);
- }
+ }
break;
}
View
70 ext/standard/tests/network/setcookie.phpt
@@ -0,0 +1,70 @@
+--TEST--
+setcookie() tests
+--DESCRIPTION--
+--INI--
+date.timezone=UTC
+--FILE--
+<?php
+setcookie('name');
+setcookie('name', 'value');
+setcookie('name', 'space value');
+setcookie('name', 'value', 0);
+setcookie('name', 'value', $tsp = time() + 5);
+setcookie('name', 'value', $tsn = time() - 6);
+setcookie('name', 'value', $tsc = time());
+setcookie('name', 'value', 0, '/path/');
+setcookie('name', 'value', 0, '', 'domain.tld');
+setcookie('name', 'value', 0, '', '', TRUE);
+setcookie('name', 'value', 0, '', '', FALSE, TRUE);
+
+
+$expected = array(
+ 'Set-Cookie: name=',
+ 'Set-Cookie: name=value',
+ 'Set-Cookie: name=space+value',
+ 'Set-Cookie: name=value',
+ 'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsp).' GMT; Max-Age=5',
+ 'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsn).' GMT; Max-Age=-6',
+ 'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsc).' GMT; Max-Age=0',
+ 'Set-Cookie: name=value; path=/path/',
+ 'Set-Cookie: name=value; domain=domain.tld',
+ 'Set-Cookie: name=value; secure',
+ 'Set-Cookie: name=value; httponly'
+);
+
+$headers = headers_list();
+if (($i = count($expected)) > count($headers))
+{
+ echo "Less headers are being sent than expected - aborting";
+ return;
+}
+
+do
+{
+ if (strncmp(current($headers), 'Set-Cookie:', 11) !== 0)
+ {
+ continue;
+ }
+
+ if (current($headers) === current($expected))
+ {
+ $i--;
+ }
+ else
+ {
+ echo "Header mismatch:\n\tExpected: "
+ .current($expected)
+ ."\n\tReceived: ".current($headers)."\n";
+ }
+
+ next($expected);
+}
+while (next($headers) !== FALSE);
+
+echo ($i === 0)
+ ? 'OK'
+ : 'A total of '.$i.' errors found.';
+--EXPECTHEADERS--
+
+--EXPECT--
+OK

0 comments on commit ec2fff8

Please sign in to comment.