php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #59264 add support for unix domain sockets (unix://)
Submitted: 2010-06-16 08:45 UTC Modified: 2021-06-09 11:24 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: alexander dot krause at ed-solutions dot de Assigned: cmb (profile)
Status: Closed Package: memcached (PECL)
PHP Version: 5.3.2 OS: Gentoo
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: alexander dot krause at ed-solutions dot de
New email:
PHP Version: OS:

 

 [2010-06-16 08:45 UTC] alexander dot krause at ed-solutions dot de
Description:
------------
The normal php-memcache extension allows the use of unix domain sockets.

However these don't work with the pecl-memcached.


Reproduce code:
---------------
$m=new Memcached();

$m->addServer(
	'/tmp/memcached.sock',
	0
);
$m->set('int', 99);

echo $m->getResultMessage();
//HOSTNAME LOOKUP FAILURE

Expected result:
----------------
SUCCESS

Actual result:
--------------
HOSTNAME LOOKUP FAILURE

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-06-16 08:46 UTC] alexander dot krause at ed-solutions dot de
Sorry for the wrong host-string, it has to be:
'unix:///tmp/memcached.sock'

I tried different things...
 [2010-10-18 06:55 UTC] ruslan dot usifov at gmail dot com
If any body interesting i have add my support for various connetions types to memcached server. I change prototype of addServer method, now it's like this:

addServer(<server decl>),
<server decl> = string || array

If <server decl> is string its have follow format (in pcre manner):

udp:host:port(( |:)<weight>)* - for udp 
host:port(( |:)<weight>)* - for tcp
/path_to_memcached_sock(( |:)<weight>)* - for unix socket

If <server decl> is array its have follow members:

array(
  "type" => MEMCACHED_CONNECTION_TCP | MEMCACHED_CONNECTION_UDP | MEMCACHED_CONNECTION_UNIX_SOCKET,
  "host" => <host>,
  "port" => <port, ignore if type == MEMCACHED_CONNECTION_UNIX_SOCKET>,
  "weight" => <weight>)

addServers, have similar declaration, except, its accept a list of <server decl>


Session save_path have follow declaration (string):

save_path=<server decl>(,<server decl>)*

diff -r 4140351daad9 php_memcached.c
--- a/php_memcached.c	Fri Oct 15 22:20:56 2010 +0400
+++ b/php_memcached.c	Mon Oct 18 14:36:41 2010 +0400
@@ -204,6 +204,173 @@
 static memcached_return php_memc_do_stats_callback(memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
 static memcached_return php_memc_do_version_callback(memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
 
+/****************************************
+  php_memcached_servers_add_string
+****************************************/
+#define HUGE_STRING_LEN 8196
+
+memcached_return php_memcached_servers_add_string(memcached_st *memc_sess, char* buffer)
+{
+	memcached_return status;
+	char *ptr, *ptr2;
+	in_port_t port = 0;
+	uint32_t weight = 0;
+
+	if(strstr(buffer, "udp:"))
+	{
+		ptr= index(&buffer[4], ':');
+
+		if (ptr)
+		{
+			ptr[0]= 0;
+			ptr++;
+
+			port= (in_port_t) strtoul(ptr, (char **)NULL, 10);
+		};
+
+		ptr2= index(ptr, ' ');
+
+		if (! ptr2)
+			ptr2= index(ptr, ':');
+
+		if (ptr2)
+		{
+			ptr2++;
+			weight = (uint32_t) strtoul(ptr2, (char **)NULL, 10);
+		};
+
+		status = memcached_server_add_udp_with_weight(memc_sess, buffer, port, weight);
+	}
+	else if(strchr(buffer, '/') == buffer)
+	{
+		ptr2= index(buffer, ' ');
+
+		if (! ptr2)
+			ptr2= index(buffer, ':');
+
+		if (ptr2)
+		{
+			ptr2[0] = 0;
+			ptr2++;
+			weight = (uint32_t) strtoul(ptr2, (char **)NULL, 10);
+		};
+
+		status = memcached_server_add_unix_socket_with_weight(memc_sess, buffer, weight);
+	}
+	else if(index(buffer, ':'))
+	{
+		ptr= index(buffer, ':');
+
+		if (ptr)
+		{
+			ptr[0]= 0;
+			ptr++;
+
+			port= (in_port_t) strtoul(ptr, (char **)NULL, 10);
+		};
+
+		ptr2= index(ptr, ' ');
+
+		if (! ptr2)
+			ptr2= index(ptr, ':');
+
+		if (ptr2)
+		{
+			ptr2++;
+			weight = (uint32_t) strtoul(ptr2, (char **)NULL, 10);
+		};
+
+		status = memcached_server_add_with_weight(memc_sess, buffer, port, weight);
+	};
+
+	return status;
+};
+
+int php_memcached_servers_add(memcached_st *memc, zval** entry TSRMLS_DC)
+{
+	int retval = 0;
+	memcached_return status;
+
+	if(Z_TYPE_PP(entry) == IS_STRING)
+	{
+		char buffer[HUGE_STRING_LEN];
+		size_t length= Z_STRLEN_PP(entry);
+		memcpy(buffer, Z_STRVAL_PP(entry), length);
+		buffer[length]= 0;
+
+		status = php_memcached_servers_add_string(memc, buffer);
+
+		if (php_memc_handle_error(status TSRMLS_CC) < 0){
+			retval = 1;
+		};
+	}
+	else if(Z_TYPE_PP(entry) == IS_ARRAY)
+	{
+		zval **z_host, **z_port, **z_weight, **z_type = NULL;
+
+		if(zend_hash_find(Z_ARRVAL_PP(entry), "type", sizeof("type"), (void **)&z_type) == FAILURE)
+		{
+			retval = 4;
+		}
+		else if(zend_hash_find(Z_ARRVAL_PP(entry), "host", sizeof("host"), (void **)&z_host) == FAILURE)
+		{
+			retval = 2;
+		}
+		else
+		{
+			convert_to_long_ex(z_type);
+
+			if(Z_LVAL_PP(z_type) != MEMCACHED_CONNECTION_UNIX_SOCKET)
+			{
+				if (zend_hash_find(Z_ARRVAL_PP(entry), "port", sizeof("port"), (void **)&z_port) == FAILURE)
+				{
+					retval = 3;
+				}
+				else
+				{
+					convert_to_long_ex(z_port);
+				};
+			};
+		};
+
+		if(!retval)
+		{
+			uint32_t weight = 0;
+			convert_to_string_ex(z_host);
+			
+
+			if(zend_hash_find(Z_ARRVAL_PP(entry), "weight", sizeof("weight"), (void **)&z_weight) == SUCCESS){
+				convert_to_long_ex(z_weight);
+				weight = Z_LVAL_PP(z_weight);
+			};
+
+			switch(Z_LVAL_PP(z_type)){
+				case MEMCACHED_CONNECTION_TCP:
+					status = memcached_server_add_with_weight(memc, Z_STRVAL_PP(z_host), Z_LVAL_PP(z_port), weight);
+				break;
+
+				case MEMCACHED_CONNECTION_UDP:
+					status = memcached_server_add_udp_with_weight(memc, Z_STRVAL_PP(z_host), Z_LVAL_PP(z_port), weight);
+				break;
+
+				case MEMCACHED_CONNECTION_UNIX_SOCKET:
+					status = memcached_server_add_unix_socket_with_weight(memc, Z_STRVAL_PP(z_host), weight);
+				break;
+			};
+
+			if (php_memc_handle_error(status TSRMLS_CC) != 0) {
+				retval = 1;
+			};
+		};
+	}
+	else
+	{
+		retval = 1;
+	};
+
+	return retval;
+};
+
 
 /****************************************
   Method implementations
@@ -1374,24 +1541,20 @@
    Adds the given memcache server to the list */
 PHP_METHOD(Memcached, addServer)
 {
-	char *host;
-	int   host_len;
-	long  port, weight = 0;
-	memcached_return status;
+	zval *server;
 	MEMC_METHOD_INIT_VARS;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &host, &host_len,
-							  &port, &weight) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &server) == FAILURE) {
 		return;
 	}
 
 	MEMC_METHOD_FETCH_OBJECT;
 	MEMC_G(rescode) = MEMCACHED_SUCCESS;
 
-	status = memcached_server_add_with_weight(i_obj->memc, host, port, weight);
-	if (php_memc_handle_error(status TSRMLS_CC) < 0) {
+	if(php_memcached_servers_add(i_obj->memc, &server) != 0)
+	{
 		RETURN_FALSE;
-	}
+	};
 
 	RETURN_TRUE;
 }
@@ -1403,10 +1566,7 @@
 {
 	zval *servers;
 	zval **entry;
-	zval **z_host, **z_port, **z_weight = NULL;
-	uint32_t weight = 0;
-	int   entry_size, i = 0;
-	memcached_server_st *list = NULL;
+	int i = 0;
 	memcached_return status;
 	MEMC_METHOD_INIT_VARS;
 
@@ -1421,61 +1581,25 @@
 		 zend_hash_get_current_data(Z_ARRVAL_P(servers), (void **)&entry) == SUCCESS;
 		 zend_hash_move_forward(Z_ARRVAL_P(servers)), i++) {
 
-		if (Z_TYPE_PP(entry) != IS_ARRAY) {
-			php_error_docref(NULL TSRMLS_CC, E_WARNING, "server list entry #%d is not an array", i+1);
-			continue;
-		}
-
-		entry_size = zend_hash_num_elements(Z_ARRVAL_PP(entry));
-
-		if (entry_size > 1) {
-			zend_hash_internal_pointer_reset(Z_ARRVAL_PP(entry));
-
-			/* Check that we have a host */
-			if (zend_hash_get_current_data(Z_ARRVAL_PP(entry), (void **)&z_host) == FAILURE) {
+		switch(php_memcached_servers_add(i_obj->memc, entry TSRMLS_CC))
+		{
+			case 1:
+				php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not add entry #%d to the server list", i+1);
+			break;
+
+			case 2:
 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not get server host for entry #%d", i+1);
-				continue;
-			}
-
-			/* Check that we have a port */
-			if (zend_hash_move_forward(Z_ARRVAL_PP(entry)) == FAILURE ||
-				zend_hash_get_current_data(Z_ARRVAL_PP(entry), (void **)&z_port) == FAILURE) {
+			break;
+
+			case 3:
 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not get server port for entry #%d", i+1);
-				continue;
-			}
-
-			convert_to_string_ex(z_host);
-			convert_to_long_ex(z_port);
-
-			weight = 0;
-			if (entry_size > 2) {
-				/* Try to get weight */
-				if (zend_hash_move_forward(Z_ARRVAL_PP(entry)) == FAILURE ||
-					zend_hash_get_current_data(Z_ARRVAL_PP(entry), (void **)&z_weight) == FAILURE) {
-					php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not get server weight for entry #%d", i+1);
-				}
-
-				convert_to_long_ex(z_weight);
-				weight = Z_LVAL_PP(z_weight);
-			}
-
-			list = memcached_server_list_append_with_weight(list, Z_STRVAL_PP(z_host),
-				Z_LVAL_PP(z_port), weight, &status);
-
-			if (php_memc_handle_error(status TSRMLS_CC) == 0) {
-				continue;
-			}
-		}
-
-		/* catch-all for all errors */
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not add entry #%d to the server list", i+1);
-	}
-
-	status = memcached_server_push(i_obj->memc, list);
-	memcached_server_list_free(list);
-	if (php_memc_handle_error(status TSRMLS_CC) < 0) {
-		RETURN_FALSE;
-	}
+			break;
+
+			case 4:
+				php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not get server type for entry #%d", i+1);
+			break;
+		};
+	};
 
 	RETURN_TRUE;
 }
@@ -2448,24 +2572,49 @@
 PS_OPEN_FUNC(memcached)
 {
 	memcached_st *memc_sess = PS_GET_MOD_DATA();
-	memcached_server_st *servers;
-	memcached_return status;
-
-	servers = memcached_servers_parse((char *)save_path);
-	if (servers) {
-		memc_sess = memcached_create(NULL);
-		if (memc_sess) {
-			status = memcached_server_push(memc_sess, servers);
-			if (status == MEMCACHED_SUCCESS) {
-				PS_SET_MOD_DATA(memc_sess);
-				return SUCCESS;
+	memc_sess = memcached_create(NULL);
+
+	if (memc_sess)
+	{
+		const char *begin_ptr;
+		const char *end_ptr;
+		char *string;
+		memcached_return status;
+		end_ptr= (char *)save_path + strlen(save_path);
+
+		for (begin_ptr= (char *)save_path, string= index((char *)save_path, ','); 
+	       begin_ptr != end_ptr; 
+	       string= index(begin_ptr, ','))
+		{
+			char buffer[HUGE_STRING_LEN];
+
+			if (string)
+			{
+				memcpy(buffer, begin_ptr, (size_t) (string - begin_ptr));
+				buffer[(unsigned int)(string - begin_ptr)]= 0;
+				begin_ptr= string+1;
 			}
-		} else {
-			php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not allocate libmemcached structure");
-		}
-	} else {
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to parse session.save_path");
+			else
+			{
+				size_t length= strlen(begin_ptr);
+				memcpy(buffer, begin_ptr, length);
+				buffer[length]= 0;
+				begin_ptr= end_ptr;
+			};
+
+			status = php_memcached_servers_add_string(memc_sess, buffer);
+
+			if (isspace(*begin_ptr))
+				begin_ptr++;
+		};
+
+		PS_SET_MOD_DATA(memc_sess);
+		return SUCCESS;
 	}
+	else
+	{
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not allocate libmemcached structure");
+	};
 
 	PS_SET_MOD_DATA(NULL);
 	return FAILURE;
@@ -2998,6 +3147,19 @@
     php_session_register_module(ps_memcached_ptr);
 #endif
 
+	/* CONST_MEMC_START */
+	REGISTER_LONG_CONSTANT("MEMCACHED_CONNECTION_UDP",
+		MEMCACHED_CONNECTION_UDP,
+		CONST_CS | CONST_PERSISTENT);
+
+	REGISTER_LONG_CONSTANT("MEMCACHED_CONNECTION_TCP",
+		MEMCACHED_CONNECTION_TCP,
+		CONST_CS | CONST_PERSISTENT);
+
+	REGISTER_LONG_CONSTANT("MEMCACHED_CONNECTION_UNIX_SOCKET",
+		MEMCACHED_CONNECTION_UNIX_SOCKET,
+		CONST_CS | CONST_PERSISTENT);
+
 	return SUCCESS;
 }
 /* }}} */
 [2021-06-09 11:24 UTC] cmb@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: cmb
 [2021-06-09 11:24 UTC] cmb@php.net
The memcached bug tracker is now on Github[1].  If this is still
an issue with the current memcached version, please report there.

[1] <https://github.com/php-memcached-dev/php-memcached/issues>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 11:01:30 2024 UTC