diff options
author | Andrey Hristov <andrey@php.net> | 2013-01-15 10:04:59 +0100 |
---|---|---|
committer | Andrey Hristov <andrey@php.net> | 2013-01-15 10:04:59 +0100 |
commit | 1ff43522630f0f98c20e884890f77e6593a43f3b (patch) | |
tree | d567b8d483870f97f2c88e6a020e2eaccdb633ec /ext/mysqlnd/mysqlnd_wireprotocol.c | |
parent | be07f815f240803fe7a48a5fb3d68a169bef4707 (diff) | |
download | php-git-1ff43522630f0f98c20e884890f77e6593a43f3b.tar.gz |
Add support for connect attributes, as of MySQL 5.6
Diffstat (limited to 'ext/mysqlnd/mysqlnd_wireprotocol.c')
-rw-r--r-- | ext/mysqlnd/mysqlnd_wireprotocol.c | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 7c3bf1395f..669970789b 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -212,6 +212,24 @@ php_mysqlnd_net_store_length(zend_uchar *packet, uint64_t length) /* }}} */ +/* {{{ php_mysqlnd_net_store_length_size */ +size_t +php_mysqlnd_net_store_length_size(uint64_t length) +{ + if (length < (uint64_t) L64(251)) { + return 1; + } + if (length < (uint64_t) L64(65536)) { + return 3; + } + if (length < (uint64_t) L64(16777216)) { + return 4; + } + return 8; +} +/* }}} */ + + /* {{{ php_mysqlnd_read_error_from_line */ static enum_func_status php_mysqlnd_read_error_from_line(zend_uchar *buf, size_t buf_len, @@ -459,7 +477,7 @@ void php_mysqlnd_greet_free_mem(void * _packet, zend_bool stack_allocation TSRML /* }}} */ -#define AUTH_WRITE_BUFFER_LEN (MYSQLND_HEADER_SIZE + MYSQLND_MAX_ALLOWED_USER_LEN + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1 + 1024) +#define AUTH_WRITE_BUFFER_LEN (MYSQLND_HEADER_SIZE + MYSQLND_MAX_ALLOWED_USER_LEN + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1 + 4096) /* {{{ php_mysqlnd_auth_write */ static @@ -540,6 +558,52 @@ size_t php_mysqlnd_auth_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC p+= len; *p++= '\0'; } + + if (packet->connect_attr && zend_hash_num_elements(packet->connect_attr)) { + HashPosition pos_value; + const char ** entry_value; + size_t ca_payload_len = 0; + zend_hash_internal_pointer_reset_ex(packet->connect_attr, &pos_value); + while (SUCCESS == zend_hash_get_current_data_ex(packet->connect_attr, (void **)&entry_value, &pos_value)) { + char *s_key; + unsigned int s_len; + unsigned long num_key; + size_t value_len = strlen(*entry_value); + + if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(packet->connect_attr, &s_key, &s_len, &num_key, 0, &pos_value)) { + ca_payload_len += php_mysqlnd_net_store_length_size(s_len); + ca_payload_len += s_len; + ca_payload_len += php_mysqlnd_net_store_length_size(value_len); + ca_payload_len += value_len; + } + zend_hash_move_forward_ex(conn->options->connect_attr, &pos_value); + } + + if ((sizeof(buffer) - (p - buffer)) >= (ca_payload_len + php_mysqlnd_net_store_length_size(ca_payload_len))) { + p = php_mysqlnd_net_store_length(p, ca_payload_len); + + zend_hash_internal_pointer_reset_ex(packet->connect_attr, &pos_value); + while (SUCCESS == zend_hash_get_current_data_ex(packet->connect_attr, (void **)&entry_value, &pos_value)) { + char *s_key; + unsigned int s_len; + unsigned long num_key; + size_t value_len = strlen(*entry_value); + if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(packet->connect_attr, &s_key, &s_len, &num_key, 0, &pos_value)) { + /* copy key */ + p = php_mysqlnd_net_store_length(p, s_len); + memcpy(p, s_key, s_len); + p+= s_len; + /* copy value */ + p = php_mysqlnd_net_store_length(p, value_len); + memcpy(p, *entry_value, value_len); + p+= value_len; + } + zend_hash_move_forward_ex(conn->options->connect_attr, &pos_value); + } + } else { + /* cannot put the data - skip */ + } + } } if (packet->is_change_user_packet) { if (PASS != conn->m->simple_command(conn, COM_CHANGE_USER, buffer + MYSQLND_HEADER_SIZE, p - buffer - MYSQLND_HEADER_SIZE, |