Re: Request for PECL account to maintain AMQP extension
| From: | Brad Rodriguez | Date: | Fri, 15 Oct 2010 07:25:00 +0000 |
| Subject: | Re: Request for PECL account to maintain AMQP extension | ||
| References: | 1 2 | Groups: | php.pecl.dev |
| Request: | Send a blank email to pecl-dev+get-7769@lists.php.net to get a copy of this message | ||
Ahh, gotcha.
Here it is with .txt extension.
-Brad
On Oct 15, 2010, at 12:21 AM, Ferenc Kovacs wrote:
>
>
> On Fri, Oct 15, 2010 at 9:08 AM, Brad Rodriguez <brodriguez@rubiconproject.com> wrote:
> Hello PECL Dev,
>
> My name is Brad Rodriguez and I have been working with Pieter, one of the current maintainers
> of the AMQP PHP extension, to update and add new features.
>
> I would like to request your approval for a PECL account so I can commit changes to the SVN
> repo.
>
> I have attached a patch file as a code sample of my recent work on the project.
>
> Thanks.
>
> -Brad
>
>
> --
> PECL development discussion Mailing List (http://pecl.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
> Hi, try to send the attachment with txt extension, or the mailing list will remove it.
>
> Tyrael
Index: amqp.c =================================================================== --- amqp.c (revision 304351) +++ amqp.c (working copy) @@ -41,8 +41,9 @@ #include <amqp_framing.h> #include <unistd.h> +#include <string.h> -#define FRAME_MAX 131072 /* max length (size) of frame */ +#define FRAME_MAX 131072 /* max length (size) of frame */ #define HEADER_FOOTER_SIZE 8 /* 7 bytes up front, then payload, then 1 byte footer */ #define PORT 5672 /* default AMQP port */ #define PORT_STR "5672" @@ -76,6 +77,15 @@ zend_object zo; char is_connected; char is_channel_connected; + char login[32]; + int char_len; + char password[32]; + int password_len; + char host[1024]; + int host_len; + char vhost[32]; + int vhost_len; + int port; int fd; amqp_connection_state_t conn; } amqp_object; @@ -108,6 +118,35 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_isConnected, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_connect, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_disconnect, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_reconnect, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setLogin, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, login) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setPassword, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, password) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setHost, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, host) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setPort, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, port) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setVhost, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, vhost) +ZEND_END_ARG_INFO() + /* amqp_queue_class ARG_INFO definition */ ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_queue_class__construct, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) ZEND_ARG_INFO(0, amqp_connection) @@ -186,8 +225,16 @@ *Every user visible function must have an entry in amqp_functions[]. */ zend_function_entry amqp_class_functions[] = { - PHP_ME(amqp_class, __construct, arginfo_amqp_class__construct, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, __construct, arginfo_amqp_class__construct, ZEND_ACC_PUBLIC) PHP_ME(amqp_class, isConnected, arginfo_amqp_class_isConnected, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, connect, arginfo_amqp_class_connect, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, disconnect, arginfo_amqp_class_disconnect, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, reconnect, arginfo_amqp_class_reconnect, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setLogin, arginfo_amqp_class_setLogin, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setPassword, arginfo_amqp_class_setPassword, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setHost, arginfo_amqp_class_setHost, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setPort, arginfo_amqp_class_setPort, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setVhost, arginfo_amqp_class_setVhost, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} /* Must be the last line in amqp_functions[] */ }; @@ -249,7 +296,7 @@ #endif -static void amqp_error(amqp_rpc_reply_t x, char ** pstr) { +static void amqp_error(amqp_rpc_reply_t x, char ** pstr) { switch (x.reply_type) { case AMQP_RESPONSE_NORMAL: return; @@ -282,14 +329,86 @@ break; } default: - spprintf(pstr, 0, "Unknown server error, method id 0x%08X", x.reply.id); + spprintf(pstr, 0, "Unknown server error, method id 0x%08X", x.reply.id); break; } break; } } +/* php_amqp_connect + handles connecting to amqp + called by connect() and reconnect() + */ +static void php_amqp_connect(amqp_object *ctx) +{ + char str[256]; + char ** pstr = (char **) &str; + + /* create the connection */ + ctx->conn = amqp_new_connection(); + ctx->fd = amqp_open_socket(ctx->host, ctx->port); + if (ctx->fd < 1) { + amqp_destroy_connection(ctx->conn); + zend_throw_exception(amqp_connection_exception_class_entry, "Socket error: could not connect to host.", 0 TSRMLS_CC); + return; + } + ctx->is_connected = '\1'; + + amqp_set_sockfd(ctx->conn, ctx->fd); + + amqp_rpc_reply_t x = amqp_login(ctx->conn, ctx->vhost, 0, FRAME_MAX, AMQP_HEARBEAT, AMQP_SASL_METHOD_PLAIN, ctx->login, ctx->password); + + if (x.reply_type != AMQP_RESPONSE_NORMAL) { + amqp_error(x, pstr); + zend_throw_exception(amqp_connection_exception_class_entry, *pstr, 0 TSRMLS_CC); + return; + } + + amqp_channel_open(ctx->conn, AMQP_CHANNEL); + + x = amqp_get_rpc_reply(ctx->conn); + if (x.reply_type != AMQP_RESPONSE_NORMAL) { + amqp_error(x, pstr); + zend_throw_exception(amqp_connection_exception_class_entry, *pstr, 0 TSRMLS_CC); + return; + } + + ctx->is_channel_connected = '\1'; +} + +/* php_amqp_disconnect + handles disconnecting from amqp + called by disconnect(), reconnect(), and d_tor + */ +static void php_amqp_disconnect(amqp_object *ctx) +{ + /* + If we are trying to close the connection and the connection already closed, it will throw + SIGPIPE, which is fine, so ignore all SIGPIPES + */ + + /* Start ignoring SIGPIPE */ + int handler = signal(SIGPIPE, SIG_IGN); + + if (ctx->is_channel_connected) { + amqp_channel_close(ctx->conn, AMQP_CHANNEL, AMQP_REPLY_SUCCESS); + } + ctx->is_channel_connected = '\0'; + + if (ctx->conn && ctx->is_connected) { + amqp_destroy_connection(ctx->conn); + } + ctx->is_connected = '\0'; + if (ctx->fd) { + close(ctx->fd); + } + + /* End ignoring of SIGPIPEs */ + signal(SIGPIPE, handler); +} + /* {{{ proto amqp::__construct(string string host=localhost, int port=PORT, login=quest, string psw=quest) amqp constructor */ PHP_METHOD(amqp_class, __construct) @@ -304,8 +423,6 @@ char *psw; char *host; char *vhost; - char str[256] ; - char ** pstr = (char **) &str; int port = 0; /* Parse out the method parameters */ @@ -320,7 +437,7 @@ /* Pull the login out of the $params array */ zdata = NULL; if (iniArr && SUCCESS == zend_hash_find(HASH_OF (iniArr), "login", sizeof("login"), (void*)&zdata)) { - convert_to_string(*zdata); + convert_to_string(*zdata); } /* Validate the given login */ if (zdata && Z_STRLEN_PP(zdata) > 0) { @@ -333,7 +450,8 @@ } else { login = estrndup(INI_STR("amqp.login"), strlen(INI_STR("amqp.login")) > 32 ? 32 : strlen(INI_STR("amqp.login"))); } - + strcpy(ctx->login, login); + /* Pull the password out of the $params array */ zdata = NULL; if (iniArr && SUCCESS == zend_hash_find(HASH_OF(iniArr), "password", sizeof("password"), (void*)&zdata)) { @@ -350,6 +468,7 @@ } else { psw = estrndup(INI_STR("amqp.password"), strlen(INI_STR("amqp.password")) > 32 ? 32 : strlen(INI_STR("amqp.password"))); } + strcpy(ctx->password, psw); /* Pull the host out of the $params array */ zdata = NULL; @@ -358,15 +477,16 @@ } /* Validate the given host */ if (zdata && Z_STRLEN_PP(zdata) > 0) { - if (Z_STRLEN_PP(zdata) < 32) { + if (Z_STRLEN_PP(zdata) < 1024) { host = estrndup(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata)); } else { - zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'host' exceeds 32 characters limit.", 0 TSRMLS_CC); + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'host' exceeds 1024 character limit.", 0 TSRMLS_CC); return; } } else { - host = estrndup(INI_STR("amqp.host"), strlen(INI_STR("amqp.host")) > 32 ? 32 : strlen(INI_STR("amqp.host"))); + host = estrndup(INI_STR("amqp.host"), strlen(INI_STR("amqp.host")) > 1024 ? 1024 : strlen(INI_STR("amqp.host"))); } + strcpy(ctx->host, host); /* Pull the vhost out of the $params array */ zdata = NULL; @@ -384,6 +504,7 @@ } else { vhost = estrndup(INI_STR("amqp.vhost"), strlen(INI_STR("amqp.vhost")) > 32 ? 32 : strlen(INI_STR("amqp.vhost"))); } + strcpy(ctx->vhost, vhost); port = INI_INT("amqp.port"); @@ -391,55 +512,92 @@ convert_to_long(*zdata); port = (size_t)Z_LVAL_PP(zdata); } + ctx->port = port; + + efree(host); + efree(psw); + efree(login); + efree(vhost); +} +/* }}} */ - ctx->conn = amqp_new_connection(); - ctx->fd = amqp_open_socket(host, port); +/* {{{ proto amqp::isConnected() +check amqp connection */ +PHP_METHOD(amqp_class, isConnected) +{ + zval *id; + amqp_object *ctx; - if (ctx->fd < 1) { - efree(host); - efree(psw); - efree(login); - efree(vhost); - - amqp_destroy_connection(ctx->conn); - zend_throw_exception(amqp_connection_exception_class_entry, "Socket error: could not connect to host.", 0 TSRMLS_CC); + /* Try to pull amqp object out of method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, amqp_class_entry) == FAILURE) { + php_std_error_handling(); return; } - ctx->is_connected = '\1'; - amqp_set_sockfd(ctx->conn, ctx->fd); + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); - amqp_rpc_reply_t x = amqp_login(ctx->conn, vhost, 0, FRAME_MAX, AMQP_HEARBEAT, AMQP_SASL_METHOD_PLAIN, login, psw); + /* If the channel_connect is 1, we have a connection */ + if (ctx->is_channel_connected == '\1') { + RETURN_TRUE; + } - efree(host); - efree(psw); - efree(login); - efree(vhost); + /* We have no connection */ + RETURN_FALSE; +} - if (x.reply_type != AMQP_RESPONSE_NORMAL) { - amqp_error(x, pstr); - zend_throw_exception(amqp_connection_exception_class_entry, *pstr, 0 TSRMLS_CC); +/* }}} */ + +/* {{{ proto amqp::connect() +create amqp connection */ +PHP_METHOD(amqp_class, connect) +{ + zval *id; + amqp_object *ctx; + + /* Try to pull amqp object out of method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, amqp_class_entry) == FAILURE) { + php_std_error_handling(); return; } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + php_amqp_connect(ctx); + + RETURN_TRUE; +} - amqp_channel_open(ctx->conn, AMQP_CHANNEL); +/* }}} */ - x = amqp_get_rpc_reply(ctx->conn); - if (x.reply_type != AMQP_RESPONSE_NORMAL) { - amqp_error(x, pstr); - zend_throw_exception(amqp_connection_exception_class_entry, *pstr, 0 TSRMLS_CC); +/* {{{ proto amqp::disconnect() +destroy amqp connection */ +PHP_METHOD(amqp_class, disconnect) +{ + zval *id; + amqp_object *ctx; + + /* Try to pull amqp object out of method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, amqp_class_entry) == FAILURE) { + php_std_error_handling(); return; } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + php_amqp_disconnect(ctx); + + RETURN_TRUE; +} - ctx->is_channel_connected = '\1'; -} /* }}} */ - -/* {{{ proto amqp::isConnected() -check amqp connection */ -PHP_METHOD(amqp_class, isConnected) +/* {{{ proto amqp::reconnect() +recreate amqp connection */ +PHP_METHOD(amqp_class, reconnect) { zval *id; amqp_object *ctx; @@ -449,24 +607,178 @@ php_std_error_handling(); return; } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + if (ctx->is_connected) { + php_amqp_disconnect(ctx); + } + php_amqp_connect(ctx); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto amqp::setLogin([string login]) +set the login */ +PHP_METHOD(amqp_class, setLogin) +{ + zval *id; + amqp_object *ctx; + char *login; + int login_len; + + /* Get the login from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &login, &login_len) == FAILURE) { + RETURN_FALSE; + } + + /* Validate login length */ + if (login_len > 32) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'login' exceeds 32 characters limit.", 0 TSRMLS_CC); + return; + } + /* Get the connection object out of the store */ ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); - /* If the channel_connect is 1, we have a connection */ - if (ctx->is_channel_connected == '\1') { - RETURN_TRUE; + /* Copy the login to the amqp object */ + strcpy(ctx->login, login); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto amqp::setPassword([string password]) +set the password */ +PHP_METHOD(amqp_class, setPassword) +{ + zval *id; + amqp_object *ctx; + char *password; + int password_len; + + /* Get the password from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &password, &password_len) == FAILURE) { + RETURN_FALSE; } + + /* Validate password length */ + if (password_len > 32) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'password' exceeds 32 characters limit.", 0 TSRMLS_CC); + return; + } - /* We have no connection */ - RETURN_FALSE; + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + /* Copy the password to the amqp object */ + strcpy(ctx->password, password); + + RETURN_TRUE; } +/* }}} */ +/* {{{ proto amqp::setHost([string host]) +set the host */ +PHP_METHOD(amqp_class, setHost) +{ + zval *id; + amqp_object *ctx; + char *host; + int host_len; + + /* Get the host from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &host, &host_len) == FAILURE) { + RETURN_FALSE; + } + + /* Validate host length */ + if (host_len > 1024) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'host' exceeds 1024 character limit.", 0 TSRMLS_CC); + return; + } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + /* Copy the host to the amqp object */ + strcpy(ctx->host, host); + + RETURN_TRUE; +} /* }}} */ + +/* {{{ proto amqp::setPort([string port]) +set the port */ +PHP_METHOD(amqp_class, setPort) +{ + zval *id; + amqp_object *ctx; + char *port; + int port_len; + + /* Get the port from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &port, &port_len) == FAILURE) { + RETURN_FALSE; + } + + /* Validate port length */ + if (port_len > 32) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'port' exceeds 32 characters limit.", 0 TSRMLS_CC); + return; + } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + /* Copy the port to the amqp object */ + ctx->port = port; + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto amqp::setVhost([string vhost]) +set the vhost */ +PHP_METHOD(amqp_class, setVhost) +{ + zval *id; + amqp_object *ctx; + char *vhost; + int vhost_len; + + /* Get the vhost from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &vhost, &vhost_len) == FAILURE) { + RETURN_FALSE; + } + + /* Validate vhost length */ + if (vhost_len > 32) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'vhost' exceeds 32 characters limit.", 0 TSRMLS_CC); + return; + } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + /* Copy the vhost to the amqp object */ + strcpy(ctx->vhost, vhost); + + RETURN_TRUE; +} +/* }}} */ /* ------------------ class Queue ----------- */ -/* {{{ proto AMQPQueue::__construct(AMQPConnection cnn, [string name]) +/* {{{ proto AMQPQueue::__construct(AMQPConnection cnn, [string name]) AMQPQueue constructor */ PHP_METHOD(amqp_queue_class, __construct) @@ -631,14 +943,14 @@ if (name_len) { s.ticket = 0; s.queue.len = name_len; - s.queue.bytes = name; + s.queue.bytes = name; s.if_unused = (AMQP_IFUNUSED & parms)? 1:0; s.if_empty = (AMQP_IFEMPTY & parms)? 1:0; s.nowait = 0; } else { s.ticket = 0; s.queue.len = ctx->name_len; - s.queue.bytes = ctx->name; + s.queue.bytes = ctx->name; s.if_unused = (AMQP_IFUNUSED & parms) ? 1 : 0; s.if_empty = (AMQP_IFEMPTY & parms) ? 1 : 0; s.nowait = 0; @@ -693,7 +1005,7 @@ ctx = (amqp_queue_object *)zend_object_store_get_object(id TSRMLS_CC); /* Check that the given connection has a channel, before trying to pull the connection off the stack */ if (ctx->is_connected != '\1') { - zend_throw_exception(amqp_queue_exception_class_entry, "Could not purge queue. No connection available.", 0 TSRMLS_CC); + zend_throw_exception(amqp_queue_exception_class_entry, "Could not purge queue. No connection available.", 0 TSRMLS_CC); return; } @@ -916,7 +1228,7 @@ amqp_basic_consume_t s; s.ticket = 0; - s.queue.len = ctx->name_len; + s.queue.len = ctx->name_len; s.queue.bytes = ctx->name; s.consumer_tag.len = 0; s.consumer_tag.bytes = NULL; @@ -1005,7 +1317,7 @@ memcpy(pbuf, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len); pbuf += frame.payload.body_fragment.len; - } /* end while */ + } /* end while */ add_index_stringl(return_value, i, buf, body_received, 1); efree(buf); @@ -1025,7 +1337,7 @@ zval *id; amqp_queue_object *ctx; char *type=NULL; - int type_len; + int type_len; amqp_rpc_reply_t res; char str[256]; @@ -1073,7 +1385,7 @@ array_init(return_value); - while (1) { /* receive frames: */ + while (1) { /* receive frames: */ amqp_maybe_release_buffers(cnn->conn); result = amqp_simple_wait_frame(cnn->conn, &frame); @@ -1385,7 +1697,7 @@ /* ------------------ class Exchange ----------- */ -/* {{{ proto AMQPEexchange( AMQPConnection cnn, [string name]); //////, string type=direct, [ bit params ]); +/* {{{ proto AMQPEexchange( AMQPConnection cnn, [string name]); //////, string type=direct, [ bit params ]); declare Exchange */ PHP_METHOD(amqp_exchange_class, __construct) { @@ -1455,7 +1767,7 @@ ctx = (amqp_exchange_object *)zend_object_store_get_object(id TSRMLS_CC); if (!type_len) { - type = AMQP_EX_TYPE_DIRECT; /* default - direct */ + type = AMQP_EX_TYPE_DIRECT; /* default - direct */ type_len = 6; //strlen('direct') } @@ -1714,7 +2026,7 @@ convert_to_string(*zdata); } if (zdata && strlen(Z_STRVAL_PP(zdata)) > 0) { - props.expiration = amqp_cstring_bytes((char*)Z_STRVAL_PP(zdata)); + props.expiration = amqp_cstring_bytes((char*)Z_STRVAL_PP(zdata)); props._flags += AMQP_BASIC_EXPIRATION_FLAG; } @@ -1831,31 +2143,10 @@ static void amqp_dtor(void *object TSRMLS_DC) { - /* - If we are trying to close the connection and the connection already closed, it will throw - SIGPIPE, which is fine, so ignore all SIGPIPES - */ - - /* Start ignoring SIGPIPE */ - int handler = signal(SIGPIPE, SIG_IGN); - amqp_object *ob = (amqp_object*)object; - if (ob->is_channel_connected) { - amqp_channel_close(ob->conn, AMQP_CHANNEL, AMQP_REPLY_SUCCESS); - } + php_amqp_disconnect(ob); - if (ob->conn && ob->is_connected) { - amqp_destroy_connection(ob->conn); - } - - if (ob->fd) { - close(ob->fd); - } - - /* End ignoring of SIGPIPEs */ - signal(SIGPIPE, handler); - zend_object_std_dtor(&ob->zo TSRMLS_CC); efree(object); @@ -1930,7 +2221,7 @@ PHP_INI_ENTRY("amqp.vhost", "/", PHP_INI_ALL, NULL) PHP_INI_ENTRY("amqp.port", PORT_STR, PHP_INI_ALL, NULL) PHP_INI_ENTRY("amqp.login", "guest", PHP_INI_ALL, NULL) - PHP_INI_ENTRY("amqp.password", "guest", PHP_INI_ALL, NULL) + PHP_INI_ENTRY("amqp.password", "guest", PHP_INI_ALL, NULL) PHP_INI_END() /* {{{ PHP_MINIT_FUNCTION @@ -1968,7 +2259,7 @@ REGISTER_LONG_CONSTANT("AMQP_DURABLE", AMQP_DURABLE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_PASSIVE", AMQP_PASSIVE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_EXCLUSIVE", AMQP_EXCLUSIVE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("AMQP_AUTODELETE", AMQP_AUTODELETE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AMQP_AUTODELETE", AMQP_AUTODELETE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_INTERNAL", AMQP_INTERNAL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_NOLOCAL", AMQP_NOLOCAL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_NOACK", AMQP_NOACK, CONST_CS | CONST_PERSISTENT); @@ -1976,11 +2267,11 @@ REGISTER_LONG_CONSTANT("AMQP_IFUNUSED", AMQP_IFUNUSED, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_MANDATORY", AMQP_MANDATORY, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_IMMEDIATE", AMQP_IMMEDIATE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("AMQP_MULTIPLE", AMQP_MULTIPLE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AMQP_MULTIPLE", AMQP_MULTIPLE, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_DIRECT", AMQP_EX_TYPE_DIRECT, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_FANOUT", AMQP_EX_TYPE_FANOUT, CONST_CS | CONST_PERSISTENT); - REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_TOPIC", AMQP_EX_TYPE_TOPIC, CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_TOPIC", AMQP_EX_TYPE_TOPIC, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_HEADER", AMQP_EX_TYPE_HEADER, CONST_CS | CONST_PERSISTENT); return SUCCESS; @@ -2013,7 +2304,7 @@ php_info_print_table_header(2, "Compiled", *pstr); php_info_print_table_header(2, "AMQP protocol version", "8.0"); php_info_print_table_header(2, "Default host", "localhost"); - php_info_print_table_header(2, "Default virtual host", "/"); + php_info_print_table_header(2, "Default virtual host", "/"); php_info_print_table_header(2, "Default port", PORT_STR); php_info_print_table_header(2, "Default login", "guest"); php_info_print_table_header(2, "Default password", "guest"); Index: php_amqp.h =================================================================== --- php_amqp.h (revision 304351) +++ php_amqp.h (working copy) @@ -62,6 +62,14 @@ PHP_METHOD(amqp_class, __construct); PHP_METHOD(amqp_class, isConnected); +PHP_METHOD(amqp_class, connect); +PHP_METHOD(amqp_class, disconnect); +PHP_METHOD(amqp_class, reconnect); +PHP_METHOD(amqp_class, setLogin); +PHP_METHOD(amqp_class, setPassword); +PHP_METHOD(amqp_class, setHost); +PHP_METHOD(amqp_class, setPort); +PHP_METHOD(amqp_class, setVhost); PHP_METHOD(amqp_queue_class, __construct); PHP_METHOD(amqp_queue_class, declare);
Index: amqp.c =================================================================== --- amqp.c (revision 304351) +++ amqp.c (working copy) @@ -41,8 +41,9 @@ #include <amqp_framing.h> #include <unistd.h> +#include <string.h> -#define FRAME_MAX 131072 /* max length (size) of frame */ +#define FRAME_MAX 131072 /* max length (size) of frame */ #define HEADER_FOOTER_SIZE 8 /* 7 bytes up front, then payload, then 1 byte footer */ #define PORT 5672 /* default AMQP port */ #define PORT_STR "5672" @@ -76,6 +77,15 @@ zend_object zo; char is_connected; char is_channel_connected; + char login[32]; + int char_len; + char password[32]; + int password_len; + char host[1024]; + int host_len; + char vhost[32]; + int vhost_len; + int port; int fd; amqp_connection_state_t conn; } amqp_object; @@ -108,6 +118,35 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_isConnected, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_connect, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_disconnect, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_reconnect, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setLogin, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, login) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setPassword, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, password) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setHost, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, host) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setPort, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, port) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_class_setVhost, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) +ZEND_ARG_INFO(0, vhost) +ZEND_END_ARG_INFO() + /* amqp_queue_class ARG_INFO definition */ ZEND_BEGIN_ARG_INFO_EX(arginfo_amqp_queue_class__construct, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1) ZEND_ARG_INFO(0, amqp_connection) @@ -186,8 +225,16 @@ *Every user visible function must have an entry in amqp_functions[]. */ zend_function_entry amqp_class_functions[] = { - PHP_ME(amqp_class, __construct, arginfo_amqp_class__construct, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, __construct, arginfo_amqp_class__construct, ZEND_ACC_PUBLIC) PHP_ME(amqp_class, isConnected, arginfo_amqp_class_isConnected, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, connect, arginfo_amqp_class_connect, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, disconnect, arginfo_amqp_class_disconnect, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, reconnect, arginfo_amqp_class_reconnect, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setLogin, arginfo_amqp_class_setLogin, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setPassword, arginfo_amqp_class_setPassword, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setHost, arginfo_amqp_class_setHost, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setPort, arginfo_amqp_class_setPort, ZEND_ACC_PUBLIC) + PHP_ME(amqp_class, setVhost, arginfo_amqp_class_setVhost, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} /* Must be the last line in amqp_functions[] */ }; @@ -249,7 +296,7 @@ #endif -static void amqp_error(amqp_rpc_reply_t x, char ** pstr) { +static void amqp_error(amqp_rpc_reply_t x, char ** pstr) { switch (x.reply_type) { case AMQP_RESPONSE_NORMAL: return; @@ -282,14 +329,86 @@ break; } default: - spprintf(pstr, 0, "Unknown server error, method id 0x%08X", x.reply.id); + spprintf(pstr, 0, "Unknown server error, method id 0x%08X", x.reply.id); break; } break; } } +/* php_amqp_connect + handles connecting to amqp + called by connect() and reconnect() + */ +static void php_amqp_connect(amqp_object *ctx) +{ + char str[256]; + char ** pstr = (char **) &str; + + /* create the connection */ + ctx->conn = amqp_new_connection(); + ctx->fd = amqp_open_socket(ctx->host, ctx->port); + if (ctx->fd < 1) { + amqp_destroy_connection(ctx->conn); + zend_throw_exception(amqp_connection_exception_class_entry, "Socket error: could not connect to host.", 0 TSRMLS_CC); + return; + } + ctx->is_connected = '\1'; + + amqp_set_sockfd(ctx->conn, ctx->fd); + + amqp_rpc_reply_t x = amqp_login(ctx->conn, ctx->vhost, 0, FRAME_MAX, AMQP_HEARBEAT, AMQP_SASL_METHOD_PLAIN, ctx->login, ctx->password); + + if (x.reply_type != AMQP_RESPONSE_NORMAL) { + amqp_error(x, pstr); + zend_throw_exception(amqp_connection_exception_class_entry, *pstr, 0 TSRMLS_CC); + return; + } + + amqp_channel_open(ctx->conn, AMQP_CHANNEL); + + x = amqp_get_rpc_reply(ctx->conn); + if (x.reply_type != AMQP_RESPONSE_NORMAL) { + amqp_error(x, pstr); + zend_throw_exception(amqp_connection_exception_class_entry, *pstr, 0 TSRMLS_CC); + return; + } + + ctx->is_channel_connected = '\1'; +} + +/* php_amqp_disconnect + handles disconnecting from amqp + called by disconnect(), reconnect(), and d_tor + */ +static void php_amqp_disconnect(amqp_object *ctx) +{ + /* + If we are trying to close the connection and the connection already closed, it will throw + SIGPIPE, which is fine, so ignore all SIGPIPES + */ + + /* Start ignoring SIGPIPE */ + int handler = signal(SIGPIPE, SIG_IGN); + + if (ctx->is_channel_connected) { + amqp_channel_close(ctx->conn, AMQP_CHANNEL, AMQP_REPLY_SUCCESS); + } + ctx->is_channel_connected = '\0'; + + if (ctx->conn && ctx->is_connected) { + amqp_destroy_connection(ctx->conn); + } + ctx->is_connected = '\0'; + if (ctx->fd) { + close(ctx->fd); + } + + /* End ignoring of SIGPIPEs */ + signal(SIGPIPE, handler); +} + /* {{{ proto amqp::__construct(string string host=localhost, int port=PORT, login=quest, string psw=quest) amqp constructor */ PHP_METHOD(amqp_class, __construct) @@ -304,8 +423,6 @@ char *psw; char *host; char *vhost; - char str[256] ; - char ** pstr = (char **) &str; int port = 0; /* Parse out the method parameters */ @@ -320,7 +437,7 @@ /* Pull the login out of the $params array */ zdata = NULL; if (iniArr && SUCCESS == zend_hash_find(HASH_OF (iniArr), "login", sizeof("login"), (void*)&zdata)) { - convert_to_string(*zdata); + convert_to_string(*zdata); } /* Validate the given login */ if (zdata && Z_STRLEN_PP(zdata) > 0) { @@ -333,7 +450,8 @@ } else { login = estrndup(INI_STR("amqp.login"), strlen(INI_STR("amqp.login")) > 32 ? 32 : strlen(INI_STR("amqp.login"))); } - + strcpy(ctx->login, login); + /* Pull the password out of the $params array */ zdata = NULL; if (iniArr && SUCCESS == zend_hash_find(HASH_OF(iniArr), "password", sizeof("password"), (void*)&zdata)) { @@ -350,6 +468,7 @@ } else { psw = estrndup(INI_STR("amqp.password"), strlen(INI_STR("amqp.password")) > 32 ? 32 : strlen(INI_STR("amqp.password"))); } + strcpy(ctx->password, psw); /* Pull the host out of the $params array */ zdata = NULL; @@ -358,15 +477,16 @@ } /* Validate the given host */ if (zdata && Z_STRLEN_PP(zdata) > 0) { - if (Z_STRLEN_PP(zdata) < 32) { + if (Z_STRLEN_PP(zdata) < 1024) { host = estrndup(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata)); } else { - zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'host' exceeds 32 characters limit.", 0 TSRMLS_CC); + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'host' exceeds 1024 character limit.", 0 TSRMLS_CC); return; } } else { - host = estrndup(INI_STR("amqp.host"), strlen(INI_STR("amqp.host")) > 32 ? 32 : strlen(INI_STR("amqp.host"))); + host = estrndup(INI_STR("amqp.host"), strlen(INI_STR("amqp.host")) > 1024 ? 1024 : strlen(INI_STR("amqp.host"))); } + strcpy(ctx->host, host); /* Pull the vhost out of the $params array */ zdata = NULL; @@ -384,6 +504,7 @@ } else { vhost = estrndup(INI_STR("amqp.vhost"), strlen(INI_STR("amqp.vhost")) > 32 ? 32 : strlen(INI_STR("amqp.vhost"))); } + strcpy(ctx->vhost, vhost); port = INI_INT("amqp.port"); @@ -391,55 +512,92 @@ convert_to_long(*zdata); port = (size_t)Z_LVAL_PP(zdata); } + ctx->port = port; + + efree(host); + efree(psw); + efree(login); + efree(vhost); +} +/* }}} */ - ctx->conn = amqp_new_connection(); - ctx->fd = amqp_open_socket(host, port); +/* {{{ proto amqp::isConnected() +check amqp connection */ +PHP_METHOD(amqp_class, isConnected) +{ + zval *id; + amqp_object *ctx; - if (ctx->fd < 1) { - efree(host); - efree(psw); - efree(login); - efree(vhost); - - amqp_destroy_connection(ctx->conn); - zend_throw_exception(amqp_connection_exception_class_entry, "Socket error: could not connect to host.", 0 TSRMLS_CC); + /* Try to pull amqp object out of method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, amqp_class_entry) == FAILURE) { + php_std_error_handling(); return; } - ctx->is_connected = '\1'; - amqp_set_sockfd(ctx->conn, ctx->fd); + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); - amqp_rpc_reply_t x = amqp_login(ctx->conn, vhost, 0, FRAME_MAX, AMQP_HEARBEAT, AMQP_SASL_METHOD_PLAIN, login, psw); + /* If the channel_connect is 1, we have a connection */ + if (ctx->is_channel_connected == '\1') { + RETURN_TRUE; + } - efree(host); - efree(psw); - efree(login); - efree(vhost); + /* We have no connection */ + RETURN_FALSE; +} - if (x.reply_type != AMQP_RESPONSE_NORMAL) { - amqp_error(x, pstr); - zend_throw_exception(amqp_connection_exception_class_entry, *pstr, 0 TSRMLS_CC); +/* }}} */ + +/* {{{ proto amqp::connect() +create amqp connection */ +PHP_METHOD(amqp_class, connect) +{ + zval *id; + amqp_object *ctx; + + /* Try to pull amqp object out of method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, amqp_class_entry) == FAILURE) { + php_std_error_handling(); return; } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + php_amqp_connect(ctx); + + RETURN_TRUE; +} - amqp_channel_open(ctx->conn, AMQP_CHANNEL); +/* }}} */ - x = amqp_get_rpc_reply(ctx->conn); - if (x.reply_type != AMQP_RESPONSE_NORMAL) { - amqp_error(x, pstr); - zend_throw_exception(amqp_connection_exception_class_entry, *pstr, 0 TSRMLS_CC); +/* {{{ proto amqp::disconnect() +destroy amqp connection */ +PHP_METHOD(amqp_class, disconnect) +{ + zval *id; + amqp_object *ctx; + + /* Try to pull amqp object out of method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, amqp_class_entry) == FAILURE) { + php_std_error_handling(); return; } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + php_amqp_disconnect(ctx); + + RETURN_TRUE; +} - ctx->is_channel_connected = '\1'; -} /* }}} */ - -/* {{{ proto amqp::isConnected() -check amqp connection */ -PHP_METHOD(amqp_class, isConnected) +/* {{{ proto amqp::reconnect() +recreate amqp connection */ +PHP_METHOD(amqp_class, reconnect) { zval *id; amqp_object *ctx; @@ -449,24 +607,178 @@ php_std_error_handling(); return; } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + if (ctx->is_connected) { + php_amqp_disconnect(ctx); + } + php_amqp_connect(ctx); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto amqp::setLogin([string login]) +set the login */ +PHP_METHOD(amqp_class, setLogin) +{ + zval *id; + amqp_object *ctx; + char *login; + int login_len; + + /* Get the login from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &login, &login_len) == FAILURE) { + RETURN_FALSE; + } + + /* Validate login length */ + if (login_len > 32) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'login' exceeds 32 characters limit.", 0 TSRMLS_CC); + return; + } + /* Get the connection object out of the store */ ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); - /* If the channel_connect is 1, we have a connection */ - if (ctx->is_channel_connected == '\1') { - RETURN_TRUE; + /* Copy the login to the amqp object */ + strcpy(ctx->login, login); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto amqp::setPassword([string password]) +set the password */ +PHP_METHOD(amqp_class, setPassword) +{ + zval *id; + amqp_object *ctx; + char *password; + int password_len; + + /* Get the password from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &password, &password_len) == FAILURE) { + RETURN_FALSE; } + + /* Validate password length */ + if (password_len > 32) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'password' exceeds 32 characters limit.", 0 TSRMLS_CC); + return; + } - /* We have no connection */ - RETURN_FALSE; + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + /* Copy the password to the amqp object */ + strcpy(ctx->password, password); + + RETURN_TRUE; } +/* }}} */ +/* {{{ proto amqp::setHost([string host]) +set the host */ +PHP_METHOD(amqp_class, setHost) +{ + zval *id; + amqp_object *ctx; + char *host; + int host_len; + + /* Get the host from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &host, &host_len) == FAILURE) { + RETURN_FALSE; + } + + /* Validate host length */ + if (host_len > 1024) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'host' exceeds 1024 character limit.", 0 TSRMLS_CC); + return; + } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + /* Copy the host to the amqp object */ + strcpy(ctx->host, host); + + RETURN_TRUE; +} /* }}} */ + +/* {{{ proto amqp::setPort([string port]) +set the port */ +PHP_METHOD(amqp_class, setPort) +{ + zval *id; + amqp_object *ctx; + char *port; + int port_len; + + /* Get the port from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &port, &port_len) == FAILURE) { + RETURN_FALSE; + } + + /* Validate port length */ + if (port_len > 32) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'port' exceeds 32 characters limit.", 0 TSRMLS_CC); + return; + } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + /* Copy the port to the amqp object */ + ctx->port = port; + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto amqp::setVhost([string vhost]) +set the vhost */ +PHP_METHOD(amqp_class, setVhost) +{ + zval *id; + amqp_object *ctx; + char *vhost; + int vhost_len; + + /* Get the vhost from the method params */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sl", &id, + amqp_class_entry, &vhost, &vhost_len) == FAILURE) { + RETURN_FALSE; + } + + /* Validate vhost length */ + if (vhost_len > 32) { + zend_throw_exception(amqp_connection_exception_class_entry, "Parameter 'vhost' exceeds 32 characters limit.", 0 TSRMLS_CC); + return; + } + + /* Get the connection object out of the store */ + ctx = (amqp_object *)zend_object_store_get_object(id TSRMLS_CC); + + /* Copy the vhost to the amqp object */ + strcpy(ctx->vhost, vhost); + + RETURN_TRUE; +} +/* }}} */ /* ------------------ class Queue ----------- */ -/* {{{ proto AMQPQueue::__construct(AMQPConnection cnn, [string name]) +/* {{{ proto AMQPQueue::__construct(AMQPConnection cnn, [string name]) AMQPQueue constructor */ PHP_METHOD(amqp_queue_class, __construct) @@ -631,14 +943,14 @@ if (name_len) { s.ticket = 0; s.queue.len = name_len; - s.queue.bytes = name; + s.queue.bytes = name; s.if_unused = (AMQP_IFUNUSED & parms)? 1:0; s.if_empty = (AMQP_IFEMPTY & parms)? 1:0; s.nowait = 0; } else { s.ticket = 0; s.queue.len = ctx->name_len; - s.queue.bytes = ctx->name; + s.queue.bytes = ctx->name; s.if_unused = (AMQP_IFUNUSED & parms) ? 1 : 0; s.if_empty = (AMQP_IFEMPTY & parms) ? 1 : 0; s.nowait = 0; @@ -693,7 +1005,7 @@ ctx = (amqp_queue_object *)zend_object_store_get_object(id TSRMLS_CC); /* Check that the given connection has a channel, before trying to pull the connection off the stack */ if (ctx->is_connected != '\1') { - zend_throw_exception(amqp_queue_exception_class_entry, "Could not purge queue. No connection available.", 0 TSRMLS_CC); + zend_throw_exception(amqp_queue_exception_class_entry, "Could not purge queue. No connection available.", 0 TSRMLS_CC); return; } @@ -916,7 +1228,7 @@ amqp_basic_consume_t s; s.ticket = 0; - s.queue.len = ctx->name_len; + s.queue.len = ctx->name_len; s.queue.bytes = ctx->name; s.consumer_tag.len = 0; s.consumer_tag.bytes = NULL; @@ -1005,7 +1317,7 @@ memcpy(pbuf, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len); pbuf += frame.payload.body_fragment.len; - } /* end while */ + } /* end while */ add_index_stringl(return_value, i, buf, body_received, 1); efree(buf); @@ -1025,7 +1337,7 @@ zval *id; amqp_queue_object *ctx; char *type=NULL; - int type_len; + int type_len; amqp_rpc_reply_t res; char str[256]; @@ -1073,7 +1385,7 @@ array_init(return_value); - while (1) { /* receive frames: */ + while (1) { /* receive frames: */ amqp_maybe_release_buffers(cnn->conn); result = amqp_simple_wait_frame(cnn->conn, &frame); @@ -1385,7 +1697,7 @@ /* ------------------ class Exchange ----------- */ -/* {{{ proto AMQPEexchange( AMQPConnection cnn, [string name]); //////, string type=direct, [ bit params ]); +/* {{{ proto AMQPEexchange( AMQPConnection cnn, [string name]); //////, string type=direct, [ bit params ]); declare Exchange */ PHP_METHOD(amqp_exchange_class, __construct) { @@ -1455,7 +1767,7 @@ ctx = (amqp_exchange_object *)zend_object_store_get_object(id TSRMLS_CC); if (!type_len) { - type = AMQP_EX_TYPE_DIRECT; /* default - direct */ + type = AMQP_EX_TYPE_DIRECT; /* default - direct */ type_len = 6; //strlen('direct') } @@ -1714,7 +2026,7 @@ convert_to_string(*zdata); } if (zdata && strlen(Z_STRVAL_PP(zdata)) > 0) { - props.expiration = amqp_cstring_bytes((char*)Z_STRVAL_PP(zdata)); + props.expiration = amqp_cstring_bytes((char*)Z_STRVAL_PP(zdata)); props._flags += AMQP_BASIC_EXPIRATION_FLAG; } @@ -1831,31 +2143,10 @@ static void amqp_dtor(void *object TSRMLS_DC) { - /* - If we are trying to close the connection and the connection already closed, it will throw - SIGPIPE, which is fine, so ignore all SIGPIPES - */ - - /* Start ignoring SIGPIPE */ - int handler = signal(SIGPIPE, SIG_IGN); - amqp_object *ob = (amqp_object*)object; - if (ob->is_channel_connected) { - amqp_channel_close(ob->conn, AMQP_CHANNEL, AMQP_REPLY_SUCCESS); - } + php_amqp_disconnect(ob); - if (ob->conn && ob->is_connected) { - amqp_destroy_connection(ob->conn); - } - - if (ob->fd) { - close(ob->fd); - } - - /* End ignoring of SIGPIPEs */ - signal(SIGPIPE, handler); - zend_object_std_dtor(&ob->zo TSRMLS_CC); efree(object); @@ -1930,7 +2221,7 @@ PHP_INI_ENTRY("amqp.vhost", "/", PHP_INI_ALL, NULL) PHP_INI_ENTRY("amqp.port", PORT_STR, PHP_INI_ALL, NULL) PHP_INI_ENTRY("amqp.login", "guest", PHP_INI_ALL, NULL) - PHP_INI_ENTRY("amqp.password", "guest", PHP_INI_ALL, NULL) + PHP_INI_ENTRY("amqp.password", "guest", PHP_INI_ALL, NULL) PHP_INI_END() /* {{{ PHP_MINIT_FUNCTION @@ -1968,7 +2259,7 @@ REGISTER_LONG_CONSTANT("AMQP_DURABLE", AMQP_DURABLE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_PASSIVE", AMQP_PASSIVE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_EXCLUSIVE", AMQP_EXCLUSIVE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("AMQP_AUTODELETE", AMQP_AUTODELETE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AMQP_AUTODELETE", AMQP_AUTODELETE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_INTERNAL", AMQP_INTERNAL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_NOLOCAL", AMQP_NOLOCAL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_NOACK", AMQP_NOACK, CONST_CS | CONST_PERSISTENT); @@ -1976,11 +2267,11 @@ REGISTER_LONG_CONSTANT("AMQP_IFUNUSED", AMQP_IFUNUSED, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_MANDATORY", AMQP_MANDATORY, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AMQP_IMMEDIATE", AMQP_IMMEDIATE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("AMQP_MULTIPLE", AMQP_MULTIPLE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AMQP_MULTIPLE", AMQP_MULTIPLE, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_DIRECT", AMQP_EX_TYPE_DIRECT, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_FANOUT", AMQP_EX_TYPE_FANOUT, CONST_CS | CONST_PERSISTENT); - REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_TOPIC", AMQP_EX_TYPE_TOPIC, CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_TOPIC", AMQP_EX_TYPE_TOPIC, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("AMQP_EX_TYPE_HEADER", AMQP_EX_TYPE_HEADER, CONST_CS | CONST_PERSISTENT); return SUCCESS; @@ -2013,7 +2304,7 @@ php_info_print_table_header(2, "Compiled", *pstr); php_info_print_table_header(2, "AMQP protocol version", "8.0"); php_info_print_table_header(2, "Default host", "localhost"); - php_info_print_table_header(2, "Default virtual host", "/"); + php_info_print_table_header(2, "Default virtual host", "/"); php_info_print_table_header(2, "Default port", PORT_STR); php_info_print_table_header(2, "Default login", "guest"); php_info_print_table_header(2, "Default password", "guest"); Index: php_amqp.h =================================================================== --- php_amqp.h (revision 304351) +++ php_amqp.h (working copy) @@ -62,6 +62,14 @@ PHP_METHOD(amqp_class, __construct); PHP_METHOD(amqp_class, isConnected); +PHP_METHOD(amqp_class, connect); +PHP_METHOD(amqp_class, disconnect); +PHP_METHOD(amqp_class, reconnect); +PHP_METHOD(amqp_class, setLogin); +PHP_METHOD(amqp_class, setPassword); +PHP_METHOD(amqp_class, setHost); +PHP_METHOD(amqp_class, setPort); +PHP_METHOD(amqp_class, setVhost); PHP_METHOD(amqp_queue_class, __construct); PHP_METHOD(amqp_queue_class, declare);