Commit: 554021d21e1b2517313a377676260c188152c2eb
Author: Yasuo Ohgaki <yohg...@php.net> Sat, 10 Aug 2013 13:56:32
+0900
Parents: 678ec306557f61bf54b6df454387e7d9c3f50de5
Branches: master
Link:
http://git.php.net/?p=php-src.git;a=commitdiff;h=554021d21e1b2517313a377676260c188152c2eb
Log:
Implemented Bug #17860 Suggestion: auto detect whether session changed
Bugs:
https://bugs.php.net/17860
Changed paths:
M NEWS
M ext/session/php_session.h
M ext/session/session.c
M ext/session/tests/session_set_save_handler_basic.phpt
M ext/session/tests/session_set_save_handler_class_003.phpt
M ext/session/tests/session_set_save_handler_class_007.phpt
M ext/session/tests/session_set_save_handler_closures.phpt
A ext/session/tests/session_set_save_handler_write_short_circuit.phpt
diff --git a/NEWS b/NEWS
index f9cb504..b444b44 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ PHP
NEWS
. Fixed Bug #65315 (session.hash_function silently fallback to default md5)
(Yasuo)
. Implemented Request #54649 (Create session_serializer_name()). (Yasuo)
+ . Implemented Request #17860 (Session write short circuit). (Yasuo)
- mysqlnd:
. Disabled flag for SP OUT variables for 5.5+ servers as they are not
natively
diff --git a/ext/session/php_session.h b/ext/session/php_session.h
index e8e79f0..ba3420e 100644
--- a/ext/session/php_session.h
+++ b/ext/session/php_session.h
@@ -180,6 +180,7 @@ typedef struct _php_ps_globals {
double rfc1867_min_freq; /* session.upload_progress.min_freq */
zend_bool use_strict_mode; /* whether or not PHP accepts unknown
session ids */
+ char session_data_hash[16]; /* binary MD5 hash length */
} php_ps_globals;
typedef php_ps_globals zend_ps_globals;
diff --git a/ext/session/session.c b/ext/session/session.c
index 278f954..24299b7 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -505,8 +505,17 @@ static void php_session_initialize(TSRMLS_D) /* {{{ */
*/
}
if (val) {
+ PHP_MD5_CTX context;
+
+ /* Store read data's MD5 hash */
+ PHP_MD5Init(&context);
+ PHP_MD5Update(&context, val, vallen);
+ PHP_MD5Final(PS(session_data_hash), &context);
+
php_session_decode(val, vallen TSRMLS_CC);
efree(val);
+ } else {
+ memset(PS(session_data_hash),'\0', 16);
}
if (!PS(use_cookies) && PS(send_cookie)) {
@@ -529,7 +538,20 @@ static void php_session_save_current_state(TSRMLS_D) /*
{{{ */
val = php_session_encode(&vallen TSRMLS_CC);
if (val) {
- ret = PS(mod)->s_write(&PS(mod_data), PS(id),
val, vallen TSRMLS_CC);
+ PHP_MD5_CTX context;
+ unsigned char digest[16];
+ char md5_hash[33];
+
+ /* Generate data's MD5 hash */
+ PHP_MD5Init(&context);
+ PHP_MD5Update(&context, val, vallen);
+ PHP_MD5Final(digest, &context);
+ /* Write only when save is required */
+ if (memcmp(digest, PS(session_data_hash), 16)) {
+ ret = PS(mod)->s_write(&PS(mod_data),
PS(id), val, vallen TSRMLS_CC);
+ } else {
+ ret = SUCCESS;
+ }
efree(val);
} else {
ret = PS(mod)->s_write(&PS(mod_data), PS(id),
"", 0 TSRMLS_CC);
diff --git a/ext/session/tests/session_set_save_handler_basic.phpt
b/ext/session/tests/session_set_save_handler_basic.phpt
index 3897ba9..e8496e8 100644
--- a/ext/session/tests/session_set_save_handler_basic.phpt
+++ b/ext/session/tests/session_set_save_handler_basic.phpt
@@ -43,6 +43,7 @@ session_id($session_id);
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
session_start();
var_dump($_SESSION);
+$_SESSION['Bar'] = 'Foo';
session_write_close();
ob_end_flush();
@@ -91,5 +92,5 @@ array(3) {
["Guff"]=>
int(1234567890)
}
-Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;]
+Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;Bar|s:3:"Foo";]
Close [%s,PHPSESSID]
diff --git a/ext/session/tests/session_set_save_handler_class_003.phpt
b/ext/session/tests/session_set_save_handler_class_003.phpt
index e9a3cc2..29b3846 100644
--- a/ext/session/tests/session_set_save_handler_class_003.phpt
+++ b/ext/session/tests/session_set_save_handler_class_003.phpt
@@ -58,6 +58,7 @@ session_set_save_handler($handler);
session_start();
+$_SESSION['bar'] = 'hello';
session_write_close();
session_unset();
@@ -71,8 +72,10 @@ array(1) {
}
int(4)
string(%d) "%s"
-array(1) {
+array(2) {
["foo"]=>
string(5) "hello"
+ ["bar"]=>
+ string(5) "hello"
}
string(3) "hai"
diff --git a/ext/session/tests/session_set_save_handler_class_007.phpt
b/ext/session/tests/session_set_save_handler_class_007.phpt
index 7344ae1..55f7225 100644
--- a/ext/session/tests/session_set_save_handler_class_007.phpt
+++ b/ext/session/tests/session_set_save_handler_class_007.phpt
@@ -56,6 +56,7 @@ $handler = new MySession(2);
session_set_save_handler($handler);
session_start();
+$_SESSION['abc'] = 'xyz';
// implicit close (called by shutdown function)
echo "done\n";
ob_end_flush();
@@ -69,6 +70,6 @@ ob_end_flush();
(#2) constructor called
(#1) destructor called
done
-(#2) writing %s = foo|s:3:"bar";
+(#2) writing %s = foo|s:3:"bar";abc|s:3:"xyz";
(#2) closing %s
(#2) destructor called
diff --git a/ext/session/tests/session_set_save_handler_closures.phpt
b/ext/session/tests/session_set_save_handler_closures.phpt
index 21b2c68..1251886 100644
--- a/ext/session/tests/session_set_save_handler_closures.phpt
+++ b/ext/session/tests/session_set_save_handler_closures.phpt
@@ -42,6 +42,7 @@ echo "Starting session again..!\n";
session_id($session_id);
session_set_save_handler($open_closure, $close_closure, $read_closure,
$write_closure, $destroy_closure, $gc_closure);
session_start();
+$_SESSION['Bar'] = 'Foo';
var_dump($_SESSION);
session_write_close();
@@ -83,13 +84,15 @@ array(3) {
Starting session again..!
Open [%s,PHPSESSID]
Read [%s,%s]
-array(3) {
+array(4) {
["Blah"]=>
string(12) "Hello World!"
["Foo"]=>
bool(false)
["Guff"]=>
int(1234567890)
+ ["Bar"]=>
+ string(3) "Foo"
}
-Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;]
+Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;Bar|s:3:"Foo";]
Close [%s,PHPSESSID]
diff --git
a/ext/session/tests/session_set_save_handler_write_short_circuit.phpt
b/ext/session/tests/session_set_save_handler_write_short_circuit.phpt
new file mode 100644
index 0000000..02ca182
--- /dev/null
+++ b/ext/session/tests/session_set_save_handler_write_short_circuit.phpt
@@ -0,0 +1,104 @@
+--TEST--
+Test session_set_save_handler() function : test write short circuit
+--INI--
+session.save_path=
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : bool session_set_save_handler(callback $open, callback $close,
callback $read, callback $write, callback $destroy, callback $gc)
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_set_save_handler() : test write short circuit ***\n";
+
+require_once "save_handler.inc";
+$path = dirname(__FILE__);
+session_save_path($path);
+session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
+
+session_start();
+$session_id = session_id();
+$_SESSION["Blah"] = "Hello World!";
+$_SESSION["Foo"] = FALSE;
+$_SESSION["Guff"] = 1234567890;
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+var_dump($_SESSION);
+
+echo "Starting session again..!\n";
+session_id($session_id);
+session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
+session_start();
+var_dump($_SESSION);
+$_SESSION['Bar'] = 'Foo';
+session_write_close();
+
+echo "Starting session again..!\n";
+session_id($session_id);
+session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
+session_start();
+var_dump($_SESSION);
+// $_SESSION should be the same and should skip write()
+session_write_close();
+
+ob_end_flush();
+?>
+--EXPECTF--
+*** Testing session_set_save_handler() : test write short circuit ***
+
+Open [%s,PHPSESSID]
+Read [%s,%s]
+array(3) {
+ ["Blah"]=>
+ string(12) "Hello World!"
+ ["Foo"]=>
+ bool(false)
+ ["Guff"]=>
+ int(1234567890)
+}
+Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;]
+Close [%s,PHPSESSID]
+array(3) {
+ ["Blah"]=>
+ string(12) "Hello World!"
+ ["Foo"]=>
+ bool(false)
+ ["Guff"]=>
+ int(1234567890)
+}
+Starting session again..!
+Open [%s,PHPSESSID]
+Read [%s,%s]
+array(3) {
+ ["Blah"]=>
+ string(12) "Hello World!"
+ ["Foo"]=>
+ bool(false)
+ ["Guff"]=>
+ int(1234567890)
+}
+Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;Bar|s:3:"Foo";]
+Close [%s,PHPSESSID]
+Starting session again..!
+Open [%s,PHPSESSID]
+Read [%s,%s]
+array(4) {
+ ["Blah"]=>
+ string(12) "Hello World!"
+ ["Foo"]=>
+ bool(false)
+ ["Guff"]=>
+ int(1234567890)
+ ["Bar"]=>
+ string(3) "Foo"
+}
+Close [%s,PHPSESSID]
\ No newline at end of file
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php