@@ -99,35 +99,98 @@ static void php_memc_sess_unlock(memcached_st *memc TSRMLS_DC)
99
99
PS_OPEN_FUNC (memcached )
100
100
{
101
101
memcached_st * memc_sess = PS_GET_MOD_DATA ();
102
- memcached_server_st * servers ;
103
102
memcached_return status ;
103
+ char * p , * plist_key = NULL ;
104
+ int plist_key_len ;
104
105
105
- servers = memcached_servers_parse ((char * )save_path );
106
- if (servers ) {
107
- memc_sess = memcached_create (NULL );
108
- if (memc_sess ) {
109
- status = memcached_server_push (memc_sess , servers );
110
- memcached_server_list_free (servers );
111
-
112
- if (memcached_callback_set (memc_sess , MEMCACHED_CALLBACK_PREFIX_KEY , MEMC_G (sess_prefix )) != MEMCACHED_SUCCESS ) {
113
- PS_SET_MOD_DATA (NULL );
114
- memcached_free (memc_sess );
115
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "bad memcached key prefix in memcached.sess_prefix" );
116
- return FAILURE ;
117
- }
106
+ if (!strncmp ((char * )save_path , "PERSISTENT=" , sizeof ("PERSISTENT=" ) - 1 )) {
107
+ zend_rsrc_list_entry * le = NULL ;
108
+ char * e ;
118
109
119
- if (status == MEMCACHED_SUCCESS ) {
110
+ p = (char * )save_path + sizeof ("PERSISTENT=" ) - 1 ;
111
+ if (!* p ) {
112
+ error :
113
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Invalid persistent id for session storage" );
114
+ return FAILURE ;
115
+ }
116
+ if ((e = strchr (p , ' ' ))) {
117
+ plist_key_len = spprintf (& plist_key , 0 , "memcached_sessions:id=%.*s" , (int )(e - p ), p );
118
+ } else {
119
+ goto error ;
120
+ }
121
+ plist_key_len ++ ;
122
+ if (zend_hash_find (& EG (persistent_list ), plist_key , plist_key_len , (void * )& le ) == SUCCESS ) {
123
+ if (le -> type == php_memc_list_entry ()) {
124
+ memc_sess = (struct memc_obj * ) le -> ptr ;
120
125
PS_SET_MOD_DATA (memc_sess );
121
126
return SUCCESS ;
122
127
}
128
+ }
129
+ p = e + 1 ;
130
+ } else {
131
+ p = (char * )save_path ;
132
+ }
133
+
134
+ if (!strstr (p , "--SERVER" )) {
135
+ memcached_server_st * servers = memcached_servers_parse (p );
136
+ if (servers ) {
137
+ memc_sess = memcached_create (NULL );
138
+ if (memc_sess ) {
139
+ status = memcached_server_push (memc_sess , servers );
140
+ memcached_server_list_free (servers );
141
+
142
+ if (memcached_callback_set (memc_sess , MEMCACHED_CALLBACK_PREFIX_KEY , MEMC_G (sess_prefix )) != MEMCACHED_SUCCESS ) {
143
+ PS_SET_MOD_DATA (NULL );
144
+ if (plist_key ) {
145
+ efree (plist_key );
146
+ }
147
+ memcached_free (memc_sess );
148
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "bad memcached key prefix in memcached.sess_prefix" );
149
+ return FAILURE ;
150
+ }
151
+
152
+ if (status == MEMCACHED_SUCCESS ) {
153
+ goto success ;
154
+ }
155
+ } else {
156
+ memcached_server_list_free (servers );
157
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "could not allocate libmemcached structure" );
158
+ }
123
159
} else {
124
- memcached_server_list_free (servers );
125
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "could not allocate libmemcached structure" );
160
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "failed to parse session.save_path" );
126
161
}
127
162
} else {
128
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "failed to parse session.save_path" );
163
+ memc_sess = memcached (p , strlen (p ));
164
+ if (!memc_sess ) {
165
+ char error_buffer [1024 ];
166
+ if (libmemcached_check_configuration (p , strlen (p ), error_buffer , sizeof (error_buffer )) != MEMCACHED_SUCCESS ) {
167
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "session.save_path configuration error %s" , error_buffer );
168
+ } else {
169
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "failed to initialize memcached session storage" );
170
+ }
171
+ } else {
172
+ success :
173
+ PS_SET_MOD_DATA (memc_sess );
174
+
175
+ if (plist_key ) {
176
+ zend_rsrc_list_entry le ;
177
+
178
+ le .type = php_memc_list_entry ();
179
+ le .ptr = memc_sess ;
180
+
181
+ if (zend_hash_update (& EG (persistent_list ), (char * )plist_key , plist_key_len , (void * )& le , sizeof (le ), NULL ) == FAILURE ) {
182
+ efree (plist_key );
183
+ php_error_docref (NULL TSRMLS_CC , E_ERROR , "could not register persistent entry" );
184
+ }
185
+ efree (plist_key );
186
+ }
187
+ return SUCCESS ;
188
+ }
129
189
}
130
190
191
+ if (plist_key ) {
192
+ efree (plist_key );
193
+ }
131
194
PS_SET_MOD_DATA (NULL );
132
195
return FAILURE ;
133
196
}
0 commit comments