package.xml 0000644 0001753 0001753 00000034753 14245353430 011360 0 ustar php php
stomp
pecl.php.net
Stomp client extension
This extension allows php applications to communicate with any Stomp compliant Message Brokers through easy object oriented and procedural interfaces.
Pierrick Charron
pierrick
pierrick@php.net
yes
Gennady Feldman
gena01
gena01@php.net
yes
Xinchen Hui
laruence
laruence@php.net
yes
Remi Collet
remi
remi@php.net
yes
2022-05-31
2.0.3
2.0.1
stable
stable
PHP License
- Fix compatibility with PHP 8
7.0.0
1.4.0
openssl
stomp
2018-06-29
2.0.2
2.0.1
stable
stable
PHP License
- Fix compatibility with PHP 7.3
- Fix -Wformat issues
2.0.1
2.0.1
stable
stable
PHP License
2017-05-04
- PHP7.1 Support
2.0.0
2.0.0
beta
beta
PHP License
2016-05-24
- PHP7 Support
1.0.9
1.0.9
stable
stable
PHP License
2016-01-04
- Adding .travis.yml to enable Travis CI test runner. (Gennady)
- Adding a basic README file. (Gennady)
- Check stomp connection status after _stomp_recv. (Gennady)
- Commenting out activemq.prefetchSize hardcoded header for SUBSCRIBE frame. (Gennady)
- Make login and passcode headers optional (if no creds provided). (Gennady)
- Fixing type cast warning, introduced a new int variable. (Gennady)
- Fixing stomp_writable() check so we can catch when connect failed. (Gennady)
1.0.8
1.0.8
stable
stable
PHP License
2015-05-18
- Fix perm on source files. (Remi)
- Fixing PHP_STOMP_VERSION constant, per Remi's request. (Gennady)
1.0.7
1.0.7
stable
stable
PHP License
2015-05-15
- add LICENSE file as documentation (Remi)
- Fixed Windows compilation regression due to new TCP_NODELAY code. (Gennady Feldman)
- Fixed bug where error checking was missing after stomp_send(). (Gennady Feldman)
1.0.6
1.0.6
stable
stable
PHP License
2014-12-07
- Add two new ini options stomp.default_username and stomp.default_passowrd (Pierrick)
- General performance improvements (Pierrick)
- Fix stomp_read_frame when buffered (Pierrick)
- Fixed bug #59217 (Connections to RabbitMQ via CLI). (Pierrick).
- Fixed bug #59970 (acking a message makes rabbitmq disconnect the server). (Pierrick)
- Fixed bug #67170 (Disable Nagle's Algorithm with TCP_NODELAY, it delays sending small messages). (Yarek Tyshchenko)
- Fixed bug #68497 (Stomp client doesn't parse ERROR response on CONNECT). (Lorenzo Fontana)
- Fixed bug #64671 (Add stomp_nack and Stomp::nack functions). (Pierrick)
1.0.5
1.0.5
stable
stable
PHP License
2012-11-18
- Fix memory leak when Stomp can't write the message on the queue. (Pierrick)
- Add a buffer for receipts. (Pierrick)
- Fixed bug #62831 (Stomp module seems not initializing SSL library first).
(Patch by lwhsu at lwhsu dot org)
- Fixed bug #59972 (Message body are not binary safe). (Pierrick)
1.0.4
1.0.4
stable
stable
PHP License
2012-09-17
- Fix compatibility with 5.4
1.0.3
1.0.3
stable
stable
PHP License
2010-10-12
- Fixed bug #18772 (setTimeout usecs not honored)
1.0.2
1.0.2
stable
stable
PHP License
2010-08-13
- Fixed SSL connection bug introduced in 1.0.1
1.0.1
1.0.1
stable
stable
PHP License
2010-08-03
- Add new parameter to the constructor to allow client to send extra informations
- Add zend engine runtime cache support (introduced into trunk)
- Add new details property in the StompException class
- Add new StompException::getDetails() method
- Add the frame body content in the Stomp::Error() method
- Fixed bug #17262 (Server is not responding on win32)
1.0.0
1.0.0
stable
stable
PHP License
2010-02-11
- Bump to stable
0.4.1
0.4.1
beta
beta
PHP License
2010-01-19
- Fix compilation issue on PHP5.2 branch
0.4.0
0.4.0
beta
beta
PHP License
2010-01-17
- Adds the ability to specify an alternative class for readFrame
0.3.2
0.3.2
beta
beta
PHP License
2009-11-22
- Adds alt class
- Fixed bug #16936 (Module segfaults on readFrame if Frame > STOMP_BUFSIZE)
- Fixed bug #16933 (readFrame does not notice when server shuts down)
- Fixed bug #16930 (readFrame reports error-frames as "timeout")
0.3.1
0.3.1
beta
beta
PHP License
2009-11-08
- Fix memory leak in stomp_send and in stomp_ack
- Reduced minimum php version to 5.2.2
0.3.0
0.3.0
beta
beta
PHP License
2009-11-06
- new stomp_connect_error() function (pierrick)
- stomp_begin, stomp_abort and stomp_commit now accept additional headers (pierrick)
- new connection timeout and read timeout ini configuration (pierrick)
- Fix a memory leak in stomp_read_line (pierrick)
- Better set of test (Pierrick and Anis)
0.2.0
0.2.0
beta
beta
PHP License
2009-11-01
- Windows build fix (kalle)
- Add SSL support (pierrick)
0.1.0
0.1.0
alpha
alpha
PHP License
2009-10-30
- Initial PECL release. (pierrick)
stomp-2.0.3/CREDITS 0000644 0001753 0001753 00000000043 14245353430 012044 0 ustar php php stomp
Pierrick Charron
Xinchen Hui
stomp-2.0.3/LICENSE 0000644 0001753 0001753 00000006204 14245353430 012036 0 ustar php php --------------------------------------------------------------------
The PHP License, version 3.01
Copyright (c) 1999 - 2014 The PHP Group. All rights reserved.
--------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, is permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The name "PHP" must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact group@php.net.
4. Products derived from this software may not be called "PHP", nor
may "PHP" appear in their name, without prior written permission
from group@php.net. You may indicate that your software works in
conjunction with PHP by saying "Foo for PHP" instead of calling
it "PHP Foo" or "phpfoo"
5. The PHP Group may publish revised and/or new versions of the
license from time to time. Each version will be given a
distinguishing version number.
Once covered code has been published under a particular version
of the license, you may always continue to use it under the terms
of that version. You may also choose to use such covered code
under the terms of any subsequent version of the license
published by the PHP Group. No one other than the PHP Group has
the right to modify the terms applicable to covered code created
under this License.
6. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes PHP software, freely available from
".
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------
This software consists of voluntary contributions made by many
individuals on behalf of the PHP Group.
The PHP Group can be contacted via Email at group@php.net.
For more information on the PHP Group and the PHP project,
please see .
PHP includes the Zend Engine, freely available at
.
stomp-2.0.3/README 0000644 0001753 0001753 00000001301 14245353430 011702 0 ustar php php stomp
=====
This extension allows php applications to communicate with any Stomp compliant Message Broker(s) through easy object
oriented and procedural interfaces.
This extension currently implements STOMP 1.0 protocol: https://stomp.github.io/stomp-specification-1.0.html
[The stomp extension at the PECL Repository website](http://pecl.php.net/package/stomp)
Documentation
=============
For documentation of the functions that this extension provides can be found here: http://www.php.net/stomp
Contribute
==========
Your contributions and bugreports are highly appreciated. To contribute, fork and create a pull request. To report a
bug use the [PHP Bug Tracking System](https://bugs.php.net/)
stomp-2.0.3/config.m4 0000644 0001753 0001753 00000001440 14245353430 012535 0 ustar php php dnl config.m4 for extension stomp
PHP_ARG_ENABLE(stomp, whether to enable stomp support,
[ --enable-stomp Enable stomp support])
PHP_ARG_WITH(openssl-dir,OpenSSL dir for stomp,
[ --with-openssl-dir[=DIR] stomp: openssl install prefix], no, no)
if test "$PHP_STOMP" != "no"; then
PHP_NEW_EXTENSION(stomp, stomp.c php_stomp.c, $ext_shared)
test -z "$PHP_OPENSSL" && PHP_OPENSSL=no
if test "$PHP_OPENSSL" != "no" || test "$PHP_OPENSSL_DIR" != "no"; then
PHP_SETUP_OPENSSL(STOMP_SHARED_LIBADD,
[
AC_DEFINE(HAVE_STOMP_SSL,1,[ ])
], [
AC_MSG_ERROR([OpenSSL libraries not found.
Check the path given to --with-openssl-dir and output in config.log)
])
])
PHP_SUBST(STOMP_SHARED_LIBADD)
fi
fi
stomp-2.0.3/config.w32 0000644 0001753 0001753 00000000715 14245353430 012634 0 ustar php php // vim:ft=javascript
ARG_ENABLE("stomp", "enable stomp support", "no");
if (PHP_STOMP != "no") {
if (CHECK_LIB("ssleay32.lib", "stomp", PHP_STOMP) && CHECK_LIB("libeay32.lib", "stomp", PHP_STOMP)) {
ADD_FLAG("CFLAGS_STOMP", "/DHAVE_STOMP_SSL=1");
} else if (CHECK_LIB("libssl.lib", "stomp", PHP_STOMP) && CHECK_LIB("libcrypto.lib", "stomp", PHP_STOMP)) {
ADD_FLAG("CFLAGS_STOMP", "/DHAVE_STOMP_SSL=1");
}
EXTENSION("stomp", "stomp.c php_stomp.c");
}
stomp-2.0.3/php_stomp.c 0000644 0001753 0001753 00000110451 14245353430 013206 0 ustar php php /*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Pierrick Charron |
+----------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "zend_exceptions.h"
#include "ext/standard/info.h"
#include "ext/standard/url.h"
#include "php_stomp.h"
#include "Zend/zend_smart_str.h"
#define GET_STOMP_OBJECT() ((stomp_object_t*) ((char *)Z_OBJ_P(getThis()) - XtOffsetOf(stomp_object_t, std)))
#define FETCH_STOMP_RSRC(result, rsrc) do { \
result = zend_fetch_resource_ex(rsrc, PHP_STOMP_RES_NAME, le_stomp); \
} while (0)
#define FETCH_STOMP_OBJECT do { \
stomp_object_t *i_obj = GET_STOMP_OBJECT(); \
if (!(stomp = i_obj->stomp)) { \
php_error_docref(NULL , E_WARNING, PHP_STOMP_ERR_NO_CTR); \
RETURN_FALSE; \
} \
} while (0)
#define INIT_FRAME_HEADERS \
zend_hash_init(frame.headers, 0, NULL, ZVAL_PTR_DTOR, 0);
#define INIT_FRAME_L(frame, cmd, l) \
frame.command = cmd; \
frame.command_length = l; \
ALLOC_HASHTABLE(frame.headers); \
INIT_FRAME_HEADERS
#define INIT_FRAME(frame, cmd) INIT_FRAME_L(frame, cmd, sizeof(cmd)-1)
#define FRAME_HEADER_FROM_HASHTABLE(h, p) do { \
zval *value, _zv; \
zend_string *key; \
ZEND_HASH_FOREACH_STR_KEY_VAL((p), key, value) { \
if (key == NULL) { \
php_error_docref(NULL , E_WARNING, "Invalid argument or parameter array"); \
break; \
} else { \
if (strncmp(ZSTR_VAL(key), "content-length", sizeof("content-length")) != 0) { \
ZVAL_STR(&_zv, zval_get_string(value)); \
zend_hash_add((h), key, &_zv); \
} \
} \
} ZEND_HASH_FOREACH_END(); \
} while (0)
#define CLEAR_FRAME(frame) \
zend_hash_destroy(frame.headers); \
efree(frame.headers);
#define THROW_STOMP_EXCEPTION(excobj, errnum, error) \
ZVAL_OBJ(excobj, zend_throw_exception_ex(stomp_ce_exception, errnum, "%s", error));
#define STOMP_ERROR(errno, msg) \
STOMP_G(error_no) = errno; \
if (STOMP_G(error_msg)) { \
efree(STOMP_G(error_msg)); \
} \
STOMP_G(error_msg) = estrdup(msg); \
if (stomp_object) { \
zend_throw_exception_ex(stomp_ce_exception, errno , msg); \
}
#define STOMP_ERROR_DETAILS(errno, msg, details) \
STOMP_G(error_no) = errno; \
if (STOMP_G(error_msg)) { \
efree(STOMP_G(error_msg)); \
} \
STOMP_G(error_msg) = estrdup(msg); \
if (stomp_object) { \
zval _object, *object = &_object; \
THROW_STOMP_EXCEPTION(object, errno, msg) \
if (details) { \
zend_update_property_string(stomp_ce_exception, OBJ_FOR_PROP(object), "details", sizeof("details")-1, (char *) details ); \
} \
}
#if PHP_VERSION_ID < 70300
#define STOMP_URL_STR(a) (a)
#else
#define STOMP_URL_STR(a) ZSTR_VAL(a)
#endif
#if PHP_VERSION_ID < 80000
#define OBJ_FOR_PROP(zv) (zv)
#else
#define OBJ_FOR_PROP(zv) Z_OBJ_P(zv)
#endif
static int le_stomp;
static zend_object_handlers stomp_obj_handlers;
ZEND_DECLARE_MODULE_GLOBALS(stomp)
static PHP_GINIT_FUNCTION(stomp);
/* {{{ stomp_class_entry */
zend_class_entry *stomp_ce_stomp;
zend_class_entry *stomp_ce_exception;
zend_class_entry *stomp_ce_frame;
/* }}} */
/* {{{ arg_info */
ZEND_BEGIN_ARG_INFO_EX(stomp_no_args, 0, 0, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_connect_args, 0, 0, 0)
ZEND_ARG_INFO(0, broker)
ZEND_ARG_INFO(0, username)
ZEND_ARG_INFO(0, password)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_link_only, 0, 0, 1)
ZEND_ARG_INFO(0, link)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_send_args, 0, 0, 3)
ZEND_ARG_INFO(0, link)
ZEND_ARG_INFO(0, destination)
ZEND_ARG_INFO(0, msg)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_oop_send_args, 0, 0, 2)
ZEND_ARG_INFO(0, destination)
ZEND_ARG_INFO(0, msg)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_subscribe_args, 0, 0, 2)
ZEND_ARG_INFO(0, link)
ZEND_ARG_INFO(0, destination)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_oop_subscribe_args, 0, 0, 1)
ZEND_ARG_INFO(0, destination)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_readframe_args, 0, 0, 1)
ZEND_ARG_INFO(0, link)
ZEND_ARG_INFO(0, class_name)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_oop_readframe_args, 0, 0, 0)
ZEND_ARG_INFO(0, class_name)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_transaction_args, 0, 0, 2)
ZEND_ARG_INFO(0, link)
ZEND_ARG_INFO(0, transaction_id)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_oop_transaction_args, 0, 0, 1)
ZEND_ARG_INFO(0, transaction_id)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_ack_args, 0, 0, 2)
ZEND_ARG_INFO(0, link)
ZEND_ARG_INFO(0, msg)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_oop_ack_args, 0, 0, 1)
ZEND_ARG_INFO(0, msg)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_nack_args, 0, 0, 2)
ZEND_ARG_INFO(0, link)
ZEND_ARG_INFO(0, msg)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_oop_nack_args, 0, 0, 1)
ZEND_ARG_INFO(0, msg)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_set_read_timeout_args, 0, 0, 2)
ZEND_ARG_INFO(0, link)
ZEND_ARG_INFO(0, seconds)
ZEND_ARG_INFO(0, microseconds)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_oop_set_read_timeout_args, 0, 0, 1)
ZEND_ARG_INFO(0, seconds)
ZEND_ARG_INFO(0, microseconds)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(stomp_frame_construct_args, 0, 0, 0)
ZEND_ARG_INFO(0, command)
ZEND_ARG_ARRAY_INFO(0, headers, 1)
ZEND_ARG_INFO(0, body)
ZEND_END_ARG_INFO()
/* }}} */
/* {{{ stomp_functions */
zend_function_entry stomp_functions[] = {
PHP_FE(stomp_version, stomp_no_args)
PHP_FE(stomp_connect, stomp_connect_args)
PHP_FE(stomp_connect_error, stomp_no_args)
PHP_FE(stomp_get_session_id, stomp_link_only)
PHP_FE(stomp_close, stomp_link_only)
PHP_FE(stomp_send, stomp_send_args)
PHP_FE(stomp_subscribe, stomp_subscribe_args)
PHP_FE(stomp_has_frame, stomp_link_only)
PHP_FE(stomp_read_frame, stomp_readframe_args)
PHP_FE(stomp_unsubscribe, stomp_subscribe_args)
PHP_FE(stomp_begin, stomp_transaction_args)
PHP_FE(stomp_commit, stomp_transaction_args)
PHP_FE(stomp_abort, stomp_transaction_args)
PHP_FE(stomp_ack, stomp_ack_args)
PHP_FE(stomp_nack, stomp_nack_args)
PHP_FE(stomp_error, stomp_link_only)
PHP_FE(stomp_set_read_timeout, stomp_set_read_timeout_args)
PHP_FE(stomp_get_read_timeout, stomp_link_only)
{NULL, NULL, NULL}
};
/* }}} */
/* {{{ stomp_methods[] */
static zend_function_entry stomp_methods[] = {
PHP_FALIAS(__construct, stomp_connect, stomp_connect_args)
PHP_FALIAS(getSessionId, stomp_get_session_id, stomp_no_args)
PHP_FALIAS(__destruct, stomp_close, stomp_no_args)
PHP_FALIAS(send, stomp_send, stomp_oop_send_args)
PHP_FALIAS(subscribe, stomp_subscribe, stomp_oop_subscribe_args)
PHP_FALIAS(hasFrame, stomp_has_frame, stomp_no_args)
PHP_FALIAS(readFrame, stomp_read_frame, stomp_oop_readframe_args)
PHP_FALIAS(unsubscribe, stomp_unsubscribe, stomp_oop_subscribe_args)
PHP_FALIAS(begin, stomp_begin, stomp_oop_transaction_args)
PHP_FALIAS(commit, stomp_commit, stomp_oop_transaction_args)
PHP_FALIAS(abort, stomp_abort, stomp_oop_transaction_args)
PHP_FALIAS(ack, stomp_ack, stomp_oop_ack_args)
PHP_FALIAS(nack, stomp_nack, stomp_oop_nack_args)
PHP_FALIAS(error, stomp_error, stomp_no_args)
PHP_FALIAS(setReadTimeout, stomp_set_read_timeout, stomp_oop_set_read_timeout_args)
PHP_FALIAS(getReadTimeout, stomp_get_read_timeout, stomp_no_args)
{NULL, NULL, NULL}
};
/* }}} */
/* {{{ stomp_frame_methods[] */
static zend_function_entry stomp_frame_methods[] = {
PHP_ME(stompframe, __construct, stomp_frame_construct_args, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
/* }}} */
/* {{{ stomp_exception_methods[] */
static zend_function_entry stomp_exception_methods[] = {
PHP_ME(stompexception, getDetails, stomp_no_args, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
/* }}} */
/* {{{ stomp_module_entry */
zend_module_entry stomp_module_entry = {
STANDARD_MODULE_HEADER,
PHP_STOMP_EXTNAME,
stomp_functions,
PHP_MINIT(stomp),
PHP_MSHUTDOWN(stomp),
PHP_RINIT(stomp),
PHP_RSHUTDOWN(stomp),
PHP_MINFO(stomp),
PHP_STOMP_VERSION,
PHP_MODULE_GLOBALS(stomp),
PHP_GINIT(stomp),
NULL,
NULL,
STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("stomp.default_broker", "tcp://localhost:61613", PHP_INI_ALL, OnUpdateString, default_broker, zend_stomp_globals, stomp_globals)
STD_PHP_INI_ENTRY("stomp.default_username", "", PHP_INI_ALL, OnUpdateString, default_username, zend_stomp_globals, stomp_globals)
STD_PHP_INI_ENTRY("stomp.default_password", "", PHP_INI_ALL, OnUpdateString, default_password, zend_stomp_globals, stomp_globals)
STD_PHP_INI_ENTRY("stomp.default_read_timeout_sec", "2", PHP_INI_ALL, OnUpdateLong, read_timeout_sec, zend_stomp_globals, stomp_globals)
STD_PHP_INI_ENTRY("stomp.default_read_timeout_usec", "0", PHP_INI_ALL, OnUpdateLong, read_timeout_usec, zend_stomp_globals, stomp_globals)
STD_PHP_INI_ENTRY("stomp.default_connection_timeout_sec", "2", PHP_INI_ALL, OnUpdateLong, connection_timeout_sec, zend_stomp_globals, stomp_globals)
STD_PHP_INI_ENTRY("stomp.default_connection_timeout_usec", "0", PHP_INI_ALL, OnUpdateLong, connection_timeout_usec, zend_stomp_globals, stomp_globals)
PHP_INI_END()
/* {{{ PHP_GINIT_FUNCTION */
static PHP_GINIT_FUNCTION(stomp)
{
stomp_globals->default_broker = NULL;
stomp_globals->default_username = NULL;
stomp_globals->default_password = NULL;
stomp_globals->read_timeout_sec = 2;
stomp_globals->read_timeout_usec = 0;
stomp_globals->connection_timeout_sec = 2;
stomp_globals->connection_timeout_usec = 0;
#if HAVE_STOMP_SSL
SSL_library_init();
#endif
}
/* }}} */
ZEND_DECLARE_MODULE_GLOBALS(stomp)
#ifdef COMPILE_DL_STOMP
ZEND_GET_MODULE(stomp)
#endif
/* {{{ constructor/destructor */
static void stomp_send_disconnect(stomp_t *stomp)
{
stomp_frame_t frame = {0};
INIT_FRAME(frame, "DISCONNECT");
stomp_send(stomp, &frame );
CLEAR_FRAME(frame);
}
static void php_destroy_stomp_res(zend_resource *rsrc)
{
stomp_t *stomp = (stomp_t *) rsrc->ptr;
stomp_send_disconnect(stomp );
stomp_close(stomp);
}
static zend_object *php_stomp_new(zend_class_entry *ce)
{
stomp_object_t *intern;
intern = (stomp_object_t *) ecalloc(1, sizeof(stomp_object_t) + zend_object_properties_size(ce));
intern->stomp = NULL;
zend_object_std_init(&intern->std, ce );
intern->std.handlers = &stomp_obj_handlers;
return &intern->std;
}
/* }}} */
/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(stomp)
{
zend_class_entry ce;
/* Ressource */
le_stomp = zend_register_list_destructors_ex(php_destroy_stomp_res, NULL, PHP_STOMP_RES_NAME, module_number);
/* Register Stomp class */
INIT_CLASS_ENTRY(ce, PHP_STOMP_CLASSNAME, stomp_methods);
stomp_ce_stomp = zend_register_internal_class(&ce );
stomp_ce_stomp->create_object = php_stomp_new;
memcpy(&stomp_obj_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
stomp_obj_handlers.offset = XtOffsetOf(stomp_object_t, std);
/* Register StompFrame class */
INIT_CLASS_ENTRY(ce, PHP_STOMP_FRAME_CLASSNAME, stomp_frame_methods);
stomp_ce_frame = zend_register_internal_class(&ce );
/* Properties */
zend_declare_property_null(stomp_ce_frame, "command", sizeof("command")-1, ZEND_ACC_PUBLIC );
zend_declare_property_null(stomp_ce_frame, "headers", sizeof("headers")-1, ZEND_ACC_PUBLIC );
zend_declare_property_null(stomp_ce_frame, "body", sizeof("body")-1, ZEND_ACC_PUBLIC );
/* Register StompException class */
INIT_CLASS_ENTRY(ce, PHP_STOMP_EXCEPTION_CLASSNAME, stomp_exception_methods);
stomp_ce_exception = zend_register_internal_class_ex(&ce, zend_exception_get_default());
/* Properties */
zend_declare_property_null(stomp_ce_exception, "details", sizeof("details")-1, ZEND_ACC_PRIVATE );
/** Register INI entries **/
REGISTER_INI_ENTRIES();
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(stomp)
{
/* Unregister INI entries */
UNREGISTER_INI_ENTRIES();
return SUCCESS;
}
/* }}} */
/* {{{ PHP_RINIT_FUNCTION */
PHP_RINIT_FUNCTION(stomp)
{
STOMP_G(error_msg) = NULL;
STOMP_G(error_no) = 0;
return SUCCESS;
}
/* }}} */
/* {{{ PHP_RSHUTDOWN_FUNCTION */
PHP_RSHUTDOWN_FUNCTION(stomp)
{
if (STOMP_G(error_msg)) {
efree(STOMP_G(error_msg));
}
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(stomp)
{
php_info_print_table_start();
php_info_print_table_header(2, PHP_STOMP_EXTNAME, "enabled");
php_info_print_table_row(2, "API version", PHP_STOMP_VERSION);
#if HAVE_STOMP_SSL
php_info_print_table_row(2, "SSL Support", "enabled");
#else
php_info_print_table_row(2, "SSL Support", "disabled");
#endif
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
}
/* }}} */
/* {{{ proto string stomp_version()
Get stomp extension version */
PHP_FUNCTION(stomp_version)
{
RETURN_STRINGL(PHP_STOMP_VERSION, sizeof(PHP_STOMP_VERSION)-1);
}
/* }}} */
/* {{{ proto Stomp::__construct([string broker [, string username [, string password [, array headers]]]])
Connect to server */
PHP_FUNCTION(stomp_connect)
{
zval *stomp_object = getThis();
zval *headers = NULL;
stomp_t *stomp = NULL;
zend_string *broker = NULL, *username = NULL, *password = NULL;
php_url *url_parts;
#ifdef HAVE_STOMP_SSL
int use_ssl = 0;
#endif
if (zend_parse_parameters(ZEND_NUM_ARGS() , "|SSSa!", &broker, &username, &password, &headers) == FAILURE) {
return;
}
/* Verify that broker URI */
if (!broker) {
broker = STOMP_G(default_broker)?
zend_string_init(STOMP_G(default_broker), strlen(STOMP_G(default_broker)), 0) : NULL;
} else {
zend_string_copy(broker);
}
url_parts = php_url_parse_ex(ZSTR_VAL(broker), ZSTR_LEN(broker));
if (!url_parts || !url_parts->host) {
STOMP_ERROR(0, PHP_STOMP_ERR_INVALID_BROKER_URI);
zend_string_release(broker);
php_url_free(url_parts);
return;
}
zend_string_release(broker);
if (url_parts->scheme) {
if (strcmp(STOMP_URL_STR(url_parts->scheme), "ssl") == 0) {
#if HAVE_STOMP_SSL
use_ssl = 1;
#else
STOMP_ERROR(0, "SSL DISABLED");
php_url_free(url_parts);
return;
#endif
} else if (strcmp(STOMP_URL_STR(url_parts->scheme), "tcp") != 0) {
STOMP_ERROR(0, PHP_STOMP_ERR_INVALID_BROKER_URI_SCHEME);
php_url_free(url_parts);
return;
}
}
stomp = stomp_init();
#if HAVE_STOMP_SSL
stomp->options.use_ssl = use_ssl;
#endif
stomp->options.read_timeout_sec = STOMP_G(read_timeout_sec);
stomp->options.read_timeout_usec = STOMP_G(read_timeout_usec);
stomp->options.connect_timeout_sec = STOMP_G(connection_timeout_sec);
stomp->options.connect_timeout_usec = STOMP_G(connection_timeout_usec);
stomp->status = stomp_connect(stomp, STOMP_URL_STR(url_parts->host), url_parts->port ? url_parts->port : 61613 );
php_url_free(url_parts);
if (stomp->status) {
zval rv;
stomp_frame_t *res;
stomp_frame_t frame = {0};
int send_status;
INIT_FRAME(frame, "CONNECT");
if (!username) {
username = zend_string_init(STOMP_G(default_username), strlen(STOMP_G(default_username)), 0);
} else {
zend_string_copy(username);
}
if (!password) {
password = zend_string_init(STOMP_G(default_password), strlen(STOMP_G(default_password)), 0);
} else {
zend_string_copy(password);
}
/*
* Per Stomp 1.1 "login" and "passcode" are optional. (Also this fix makes test pass against RabbitMQ)
*/
if (ZSTR_LEN(username) > 0) {
ZVAL_STR(&rv, zend_string_copy(username));
zend_hash_str_add(frame.headers, "login", sizeof("login") - 1, &rv);
}
if (ZSTR_LEN(password)) {
ZVAL_STR(&rv, zend_string_copy(password));
zend_hash_str_add(frame.headers, "passcode", sizeof("passcode"), &rv);
}
zend_string_release(username);
zend_string_release(password);
if (NULL != headers) {
FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(headers));
}
send_status = stomp_send(stomp, &frame );
CLEAR_FRAME(frame);
if (0 == send_status) {
zval excobj;
THROW_STOMP_EXCEPTION(&excobj, stomp->errnum, stomp->error);
if (stomp->error_details) {
zend_update_property_string(stomp_ce_exception, OBJ_FOR_PROP(&excobj), "details", sizeof("details")-1, stomp->error_details );
}
return;
}
/* Retreive Response */
res = stomp_read_frame_ex(stomp, 0);
if (NULL == res) {
STOMP_ERROR(0, PHP_STOMP_ERR_SERVER_NOT_RESPONDING);
} else if (0 == strncmp("ERROR", res->command, sizeof("ERROR") - 1)) {
zval *error_msg, excobj;
if ((error_msg = zend_hash_str_find(res->headers, ZEND_STRL("message"))) != NULL) {
THROW_STOMP_EXCEPTION(&excobj, 0, ZSTR_VAL(Z_STR_P(error_msg)));
if (res->body) {
zend_update_property_string(stomp_ce_exception, OBJ_FOR_PROP(&excobj), "details", sizeof("details")-1, (char *) res->body );
}
}
stomp_free_frame(res);
} else if (0 != strncmp("CONNECTED", res->command, sizeof("CONNECTED")-1)) {
if (stomp->error) {
STOMP_ERROR_DETAILS(stomp->errnum, stomp->error, stomp->error_details);
} else {
STOMP_ERROR(0, PHP_STOMP_ERR_UNKNOWN);
}
stomp_free_frame(res);
} else {
zval *key;
if ((key = zend_hash_str_find(res->headers, ZEND_STRL("session"))) != NULL) {
if (stomp->session) {
efree(stomp->session);
}
ZEND_ASSERT(Z_TYPE_P(key) == IS_STRING);
stomp->session = estrdup(Z_STRVAL_P(key));
}
stomp_free_frame(res);
if (!stomp_object) {
RETURN_RES(zend_register_resource(stomp, le_stomp));
} else {
stomp_object_t *i_obj = GET_STOMP_OBJECT();
if (i_obj->stomp) {
stomp_close(i_obj->stomp);
}
i_obj->stomp = stomp;
RETURN_TRUE;
}
}
} else {
STOMP_ERROR_DETAILS(0, stomp->error, stomp->error_details);
}
stomp_close(stomp);
RETURN_FALSE;
}
/* }}} */
/* {{{ proto string stomp_connect_error()
Get the last connection error */
PHP_FUNCTION(stomp_connect_error)
{
if (STOMP_G(error_msg)) {
RETURN_STRING(STOMP_G(error_msg));
} else {
RETURN_NULL();
}
}
/* }}} */
/* {{{ proto string Stomp::getSessionId()
Get the current stomp session ID */
PHP_FUNCTION(stomp_get_session_id)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
if (stomp_object) {
FETCH_STOMP_OBJECT;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "r", &arg) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
if (!stomp) {
php_error_docref(NULL , E_WARNING, PHP_STOMP_ERR_NO_CTR);
RETURN_FALSE;
}
if (stomp->session) {
RETURN_STRING(stomp->session);
} else {
RETURN_FALSE;
}
}
/* }}} */
/* {{{ proto boolean Stomp::__destruct()
Close stomp connection */
PHP_FUNCTION(stomp_close)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
if (stomp_object) {
stomp_object_t *i_obj = GET_STOMP_OBJECT();
if (!(stomp = i_obj->stomp)) {
php_error_docref(NULL , E_WARNING, PHP_STOMP_ERR_NO_CTR);
RETURN_FALSE;
}
stomp_send_disconnect(stomp );
stomp_close(stomp);
i_obj->stomp = NULL;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "r", &arg) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
zend_list_close(Z_RES_P(arg));
}
RETURN_TRUE;
}
/* }}} */
/* {{{ proto boolean Stomp::send(string destination, mixed msg [, array headers])
Sends a message to a destination in the messaging system */
PHP_FUNCTION(stomp_send)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
zend_string *destination;
zval *msg, *headers = NULL, rv;
stomp_frame_t frame = {0};
int success = 0;
if (stomp_object) {
if (zend_parse_parameters(ZEND_NUM_ARGS() , "Sz|a!", &destination, &msg, &headers) == FAILURE) {
return;
}
FETCH_STOMP_OBJECT;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "rSz|a!", &arg, &destination, &msg, &headers) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
/* Verify destination */
if (0 == ZSTR_LEN(destination)) {
php_error_docref(NULL , E_WARNING, PHP_STOMP_ERR_EMPTY_DESTINATION);
RETURN_FALSE;
}
INIT_FRAME(frame, "SEND");
/* Translate a PHP array to a stomp_header array */
if (NULL != headers) {
FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(headers));
}
/* Add the destination */
ZVAL_STR(&rv, zend_string_copy(destination));
zend_hash_str_add(frame.headers, "destination", sizeof("destination") - 1, &rv);
if (Z_TYPE_P(msg) == IS_STRING) {
frame.body = Z_STRVAL_P(msg);
frame.body_length = Z_STRLEN_P(msg);
} else if (Z_TYPE_P(msg) == IS_OBJECT && instanceof_function(Z_OBJCE_P(msg), stomp_ce_frame )) {
zval *frame_obj_prop = NULL;
frame_obj_prop = zend_read_property(stomp_ce_frame, OBJ_FOR_PROP(msg), "command", sizeof("command")-1, 1, &rv);
if (Z_TYPE_P(frame_obj_prop) == IS_STRING) {
frame.command = Z_STRVAL_P(frame_obj_prop);
frame.command_length = Z_STRLEN_P(frame_obj_prop);
}
frame_obj_prop = zend_read_property(stomp_ce_frame, OBJ_FOR_PROP(msg), "body", sizeof("body")-1, 1, &rv);
if (Z_TYPE_P(frame_obj_prop) == IS_STRING) {
frame.body = Z_STRVAL_P(frame_obj_prop);
frame.body_length = Z_STRLEN_P(frame_obj_prop);
}
frame_obj_prop = zend_read_property(stomp_ce_frame, OBJ_FOR_PROP(msg), "headers", sizeof("headers")-1, 1, &rv);
if (Z_TYPE_P(frame_obj_prop) == IS_ARRAY) {
FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(frame_obj_prop));
}
} else {
php_error_docref(NULL , E_WARNING, "Expects parameter %d to be a string or a StompFrame object.", stomp_object?2:3);
CLEAR_FRAME(frame);
RETURN_FALSE;
}
if (stomp_send(stomp, &frame ) > 0) {
success = stomp_valid_receipt(stomp, &frame);
}
CLEAR_FRAME(frame);
RETURN_BOOL(success);
}
/* }}} */
/* {{{ proto boolean Stomp::subscribe(string destination [, array headers])
Register to listen to a given destination */
PHP_FUNCTION(stomp_subscribe)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
zend_string *destination;
zval *headers = NULL, rv;
stomp_frame_t frame = {0};
int success = 0;
if (stomp_object) {
if (zend_parse_parameters(ZEND_NUM_ARGS() , "S|a!", &destination, &headers) == FAILURE) {
return;
}
FETCH_STOMP_OBJECT;
} else {
zval *arg = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "rS|a!", &arg, &destination, &headers) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
/* Verify destination */
if (ZSTR_LEN(destination) == 0) {
php_error_docref(NULL , E_WARNING, PHP_STOMP_ERR_EMPTY_DESTINATION);
RETURN_FALSE;
}
INIT_FRAME(frame, "SUBSCRIBE");
/* Translate a PHP array to a stomp_header array */
if (NULL != headers) {
FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(headers));
}
/* Add the ack if not already in the headers */
if (!zend_hash_str_find(frame.headers, ZEND_STRL("ack"))) {
ZVAL_STRINGL(&rv, "client", sizeof("client") - 1);
zend_hash_str_update(frame.headers, "ack", sizeof("ack") - 1, &rv);
}
/* Add the destination */
ZVAL_STR(&rv, zend_string_copy(destination));
zend_hash_str_update(frame.headers, "destination", sizeof("destination") - 1, &rv);
/* zend_hash_str_add_ptr(frame.headers, ZEND_STRL("activemq.prefetchSize"), estrdup("1")); */
if (stomp_send(stomp, &frame ) > 0) {
success = stomp_valid_receipt(stomp, &frame);
}
CLEAR_FRAME(frame);
RETURN_BOOL(success);
}
/* }}} */
/* {{{ proto boolean Stomp::unsubscribe(string destination [, array headers])
Remove an existing subscription */
PHP_FUNCTION(stomp_unsubscribe)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
zend_string *destination;
zval *headers = NULL, rv;
stomp_frame_t frame = {0};
int success = 0;
if (stomp_object) {
if (zend_parse_parameters(ZEND_NUM_ARGS() , "S|a!", &destination, &headers) == FAILURE) {
return;
}
FETCH_STOMP_OBJECT;
} else {
zval *arg = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "rS|a!", &arg, &destination, &headers) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
/* Verify destination */
if (0 == ZSTR_LEN(destination)) {
php_error_docref(NULL , E_WARNING, PHP_STOMP_ERR_EMPTY_DESTINATION);
RETURN_FALSE;
}
INIT_FRAME(frame, "UNSUBSCRIBE");
/* Translate a PHP array to a stomp_header array */
if (NULL != headers) {
FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(headers));
}
/* Add the destination */
ZVAL_STR(&rv, zend_string_copy(destination));
zend_hash_str_add(frame.headers, "destination", sizeof("destination") - 1, &rv);
if (stomp_send(stomp, &frame ) > 0) {
success = stomp_valid_receipt(stomp, &frame);
}
CLEAR_FRAME(frame);
RETURN_BOOL(success);
}
/* }}} */
/* {{{ proto boolean Stomp::hasFrame()
Indicate whether or not there is a frame ready to read */
PHP_FUNCTION(stomp_has_frame)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
if (stomp_object) {
FETCH_STOMP_OBJECT;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "r", &arg) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
RETURN_BOOL(stomp_select(stomp) > 0);
}
/* }}} */
/* {{{ proto StompFrame Stomp::readFrame()
Read the next frame */
PHP_FUNCTION(stomp_read_frame)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
stomp_frame_t *res = NULL;
zend_string *class_name = NULL;
zend_class_entry *ce = NULL;
if (stomp_object) {
if (zend_parse_parameters(ZEND_NUM_ARGS() , "|S", &class_name) == FAILURE) {
return;
}
FETCH_STOMP_OBJECT;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "r|S", &arg, &class_name) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
if (class_name && ZSTR_LEN(class_name)) {
ce = zend_fetch_class(class_name, ZEND_FETCH_CLASS_AUTO);
if (!ce) {
php_error_docref(NULL , E_WARNING, "Could not find class '%s'", ZSTR_VAL(class_name));
ce = stomp_ce_frame;
}
} else if (stomp_object) {
ce = stomp_ce_frame;
}
if ((res = stomp_read_frame(stomp))) {
zval headers;
if (0 == strncmp("ERROR", res->command, sizeof("ERROR") - 1)) {
zval *error_msg;
if ((error_msg = zend_hash_str_find(res->headers, "message", sizeof("message") - 1)) != NULL) {
zval excobj;
THROW_STOMP_EXCEPTION(&excobj, 0, Z_STRVAL_P(error_msg));
if (res->body) {
zend_update_property_string(stomp_ce_exception, OBJ_FOR_PROP(&excobj), ZEND_STRL("details"), (char *)res->body );
}
stomp_free_frame(res);
RETURN_FALSE;
}
}
array_init(&headers);
if (res->headers) {
zend_string *key;
zval *val;
ZEND_HASH_FOREACH_STR_KEY_VAL(res->headers, key, val) {
if (!key) {
break;
}
Z_TRY_ADDREF_P(val);
zend_hash_update(Z_ARRVAL(headers), key, val);
} ZEND_HASH_FOREACH_END();
}
if (ce) {
zend_fcall_info fci;
zend_fcall_info_cache fcc;
zval retval;
object_init_ex(return_value, ce);
if (ce->constructor) {
zval cmd, body;
ZVAL_STRINGL(&cmd, res->command, res->command_length);
if (res->body) {
ZVAL_STRINGL(&body, res->body, res->body_length);
} else {
ZVAL_NULL(&body);
}
memset(&fci, 0, sizeof(fci));
memset(&fcc, 0, sizeof(fcc));
fci.size = sizeof(fci);
#if (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
fci.function_table = &ce->function_table;
#endif
/* PARAMS */
fci.param_count = 3;
fci.params = (zval*) safe_emalloc(sizeof(zval), 3, 0);
ZVAL_COPY_VALUE(&fci.params[0], &cmd);
ZVAL_COPY_VALUE(&fci.params[1], &headers);
ZVAL_COPY_VALUE(&fci.params[2], &body);
ZVAL_UNDEF(&fci.function_name);
fci.object = Z_OBJ_P(return_value);
fci.retval = &retval;
#if PHP_VERSION_ID < 80000
fci.no_separation = 1;
#endif
#if PHP_VERSION_ID < 70300
fcc.initialized = 1;
#endif
fcc.function_handler = ce->constructor;
#if (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
fcc.calling_scope = EG(scope);
#else
fcc.calling_scope = zend_get_executed_scope();
#endif
fcc.object = Z_OBJ_P(return_value);
if (zend_call_function(&fci, &fcc ) == FAILURE) {
zend_throw_exception_ex(zend_exception_get_default(), 0 , "Could not execute %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(ce->constructor->common.function_name));
} else {
zval_ptr_dtor(&retval);
}
if (fci.params) {
efree(fci.params);
}
zval_ptr_dtor(&cmd);
zval_ptr_dtor(&body);
}
zval_ptr_dtor(&headers);
} else {
array_init(return_value);
add_assoc_string_ex(return_value, "command", sizeof("command") - 1, res->command);
if (res->body) {
add_assoc_stringl_ex(return_value, "body", sizeof("body") - 1, res->body, res->body_length);
}
add_assoc_zval_ex(return_value, "headers", sizeof("headers") - 1, &headers);
}
stomp_free_frame(res);
} else {
RETURN_FALSE;
}
}
/* }}} */
/* {{{ _php_stomp_transaction */
static void _php_stomp_transaction(INTERNAL_FUNCTION_PARAMETERS, char *cmd, size_t cmd_len) {
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
zend_string *transaction_id;
stomp_frame_t frame = {0};
int success = 0;
zval *headers = NULL, rv;
if (stomp_object) {
if (zend_parse_parameters(ZEND_NUM_ARGS() , "S!|a", &transaction_id, &headers) == FAILURE) {
return;
}
FETCH_STOMP_OBJECT;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "rS!|a", &arg, &transaction_id, &headers) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
INIT_FRAME_L(frame, cmd, cmd_len);
if (transaction_id && ZSTR_LEN(transaction_id)) {
ZVAL_STR(&rv, zend_string_copy(transaction_id));
zend_hash_str_add(frame.headers, "transaction", sizeof("transaction") - 1, &rv);
}
/* Translate a PHP array to a stomp_header array */
if (NULL != headers) {
FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(headers));
}
if (stomp_send(stomp, &frame ) > 0) {
success = stomp_valid_receipt(stomp, &frame);
}
CLEAR_FRAME(frame);
RETURN_BOOL(success);
}
/* }}} */
/* {{{ proto boolean Stomp::begin(string transactionId [, array headers ])
Start a transaction */
PHP_FUNCTION(stomp_begin)
{
_php_stomp_transaction(INTERNAL_FUNCTION_PARAM_PASSTHRU, "BEGIN", sizeof("BEGIN") - 1);
}
/* }}} */
/* {{{ proto boolean Stomp::commit(string transactionId [, array headers ])
Commit a transaction in progress */
PHP_FUNCTION(stomp_commit)
{
_php_stomp_transaction(INTERNAL_FUNCTION_PARAM_PASSTHRU, "COMMIT", sizeof("COMMIT") - 1);
}
/* }}} */
/* {{{ proto boolean Stomp::abort(string transactionId [, array headers ])
Rollback a transaction in progress */
PHP_FUNCTION(stomp_abort)
{
_php_stomp_transaction(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ABORT", sizeof("ABORT") - 1);
}
/* }}} */
/* {{{ _php_stomp_acknowledgment
*/
static void _php_stomp_acknowledgment(INTERNAL_FUNCTION_PARAMETERS, char *cmd) {
zval *stomp_object = getThis();
zval *msg, *headers = NULL;
stomp_t *stomp = NULL;
stomp_frame_t frame = {0};
int success = 0;
if (stomp_object) {
if (zend_parse_parameters(ZEND_NUM_ARGS() , "z|a!", &msg, &headers) == FAILURE) {
return;
}
FETCH_STOMP_OBJECT;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "rz|a!", &arg, &msg, &headers) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
INIT_FRAME(frame, cmd);
if (NULL != headers) {
FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(headers));
}
if (Z_TYPE_P(msg) == IS_STRING) {
Z_TRY_ADDREF_P(msg);
zend_hash_str_add(frame.headers, "message-id", sizeof("message-id") - 1, msg);
} else if (Z_TYPE_P(msg) == IS_OBJECT && instanceof_function(Z_OBJCE_P(msg), stomp_ce_frame )) {
zval *frame_obj_prop, rv;
frame_obj_prop = zend_read_property(stomp_ce_frame, OBJ_FOR_PROP(msg), "headers", sizeof("headers")-1, 1, &rv);
if (Z_TYPE_P(frame_obj_prop) == IS_ARRAY) {
FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(frame_obj_prop));
}
} else {
php_error_docref(NULL, E_WARNING,
"Expects parameter %d to be a string or a StompFrame object.", stomp_object? 2 : 3);
CLEAR_FRAME(frame);
RETURN_FALSE;
}
if (stomp_send(stomp, &frame ) > 0) {
success = stomp_valid_receipt(stomp, &frame);
}
CLEAR_FRAME(frame);
RETURN_BOOL(success);
}
/* }}} */
/* {{{ proto boolean Stomp::ack(mixed msg [, array headers])
Acknowledge consumption of a message from a subscription using client acknowledgment */
PHP_FUNCTION(stomp_ack)
{
_php_stomp_acknowledgment(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ACK");
}
/* }}} */
/* {{{ proto boolean Stomp::nack(mixed msg [, array headers])
Negative Acknowledgment of a message from a subscription */
PHP_FUNCTION(stomp_nack)
{
_php_stomp_acknowledgment(INTERNAL_FUNCTION_PARAM_PASSTHRU, "NACK");
}
/* }}} */
/* {{{ proto string Stomp::error()
Get the last error message */
PHP_FUNCTION(stomp_error)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
if (stomp_object) {
FETCH_STOMP_OBJECT;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "r", &arg) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
if (stomp->error) {
if (stomp->error_details) {
char *error_msg = (char *) emalloc(strlen(stomp->error) + strlen(stomp->error_details) + 10);
strcpy(error_msg, stomp->error);
strcat(error_msg, "\n\n");
strcat(error_msg, stomp->error_details);
RETVAL_STRING(error_msg);
efree(error_msg);
} else {
RETURN_STRING(stomp->error);
}
} else {
RETURN_FALSE;
}
}
/* }}} */
/* {{{ proto void Stomp::setTimeout(int seconds [, int microseconds])
Set the timeout */
PHP_FUNCTION(stomp_set_read_timeout)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
zend_long sec = 0, usec = 0;
if (stomp_object) {
if (zend_parse_parameters(ZEND_NUM_ARGS() , "l|l", &sec, &usec) == FAILURE) {
return;
}
FETCH_STOMP_OBJECT;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "rl|l", &arg, &sec, &usec) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
stomp->options.read_timeout_sec = sec;
stomp->options.read_timeout_usec = usec;
}
/* }}} */
/* {{{ proto array Stomp::getTimeout()
Get the timeout */
PHP_FUNCTION(stomp_get_read_timeout)
{
zval *stomp_object = getThis();
stomp_t *stomp = NULL;
if (stomp_object) {
FETCH_STOMP_OBJECT;
} else {
zval *arg;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "r", &arg) == FAILURE) {
return;
}
FETCH_STOMP_RSRC(stomp, arg);
}
array_init(return_value);
add_assoc_long_ex(return_value, "sec", sizeof("sec") - 1, stomp->options.read_timeout_sec);
add_assoc_long_ex(return_value, "usec", sizeof("usec") - 1, stomp->options.read_timeout_usec);
}
/* }}} */
/* {{{ proto void StompFrame::__construct([string command [, array headers [, string body]]])
Create StompFrame object */
PHP_METHOD(stompframe, __construct)
{
zval *object = getThis();
char *command = NULL, *body = NULL;
zend_long command_length = 0, body_length = -1;
zval *headers = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() , "|sa!s", &command, &command_length, &headers, &body, &body_length) == FAILURE) {
return;
}
if (command_length > 0) {
zend_update_property_stringl(stomp_ce_frame, OBJ_FOR_PROP(object), "command", sizeof("command")-1, command, command_length );
}
if (headers) {
zend_update_property(stomp_ce_frame, OBJ_FOR_PROP(object), "headers", sizeof("headers")-1, headers );
}
if (body_length > 0) {
zend_update_property_stringl(stomp_ce_frame, OBJ_FOR_PROP(object), "body", sizeof("body")-1, body, body_length );
}
}
/* }}} */
/* {{{ proto string StompException::getDetails()
Get error details */
PHP_METHOD(stompexception, getDetails)
{
zval *object = getThis();
zval rv, *details = zend_read_property(stomp_ce_exception, OBJ_FOR_PROP(object), "details", sizeof("details")-1, 1, &rv);
RETURN_STR(zval_get_string(details));
}
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
stomp-2.0.3/php_stomp.h 0000644 0001753 0001753 00000006757 14245353430 013230 0 ustar php php /*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Pierrick Charron |
+----------------------------------------------------------------------+
*/
#ifndef PHP_STOMP_H
#define PHP_STOMP_H
#include "stomp.h"
typedef struct _stomp_object {
stomp_t *stomp;
zend_object std;
} stomp_object_t;
#define PHP_STOMP_EXTNAME "Stomp"
#define PHP_STOMP_VERSION "2.0.3"
#define PHP_STOMP_RES_NAME "stomp connection"
#define PHP_STOMP_CLASSNAME "Stomp"
#define PHP_STOMP_FRAME_CLASSNAME "StompFrame"
#define PHP_STOMP_EXCEPTION_CLASSNAME "StompException"
#define PHP_STOMP_ERR_UNKNOWN "Stomp unknown error"
#define PHP_STOMP_ERR_INVALID_BROKER_URI "Invalid Broker URI"
#define PHP_STOMP_ERR_INVALID_BROKER_URI_SCHEME "Invalid Broker URI scheme"
#define PHP_STOMP_ERR_SERVER_NOT_RESPONDING "Server is not responding"
#define PHP_STOMP_ERR_EMPTY_DESTINATION "Destination can not be empty"
#define PHP_STOMP_ERR_NO_CTR "Stomp constructor was not called"
extern zend_module_entry stomp_module_entry;
#define phpext_stomp_ptr &stomp_module_entry
#ifdef PHP_WIN32
#define PHP_STOMP_API __declspec(dllexport)
#else
#define PHP_STOMP_API
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
PHP_MINIT_FUNCTION(stomp);
PHP_MSHUTDOWN_FUNCTION(stomp);
PHP_RINIT_FUNCTION(stomp);
PHP_RSHUTDOWN_FUNCTION(stomp);
PHP_MINFO_FUNCTION(stomp);
/* Methods declarations */
PHP_FUNCTION(stomp_version);
PHP_FUNCTION(stomp_connect);
PHP_FUNCTION(stomp_connect_error);
PHP_FUNCTION(stomp_get_session_id);
PHP_FUNCTION(stomp_close);
PHP_FUNCTION(stomp_send);
PHP_FUNCTION(stomp_subscribe);
PHP_FUNCTION(stomp_has_frame);
PHP_FUNCTION(stomp_read_frame);
PHP_FUNCTION(stomp_unsubscribe);
PHP_FUNCTION(stomp_begin);
PHP_FUNCTION(stomp_commit);
PHP_FUNCTION(stomp_abort);
PHP_FUNCTION(stomp_ack);
PHP_FUNCTION(stomp_nack);
PHP_FUNCTION(stomp_error);
PHP_FUNCTION(stomp_set_read_timeout);
PHP_FUNCTION(stomp_get_read_timeout);
PHP_METHOD(stompframe, __construct);
PHP_METHOD(stompexception, getDetails);
ZEND_BEGIN_MODULE_GLOBALS(stomp)
/* INI */
char *default_broker;
long read_timeout_sec;
long read_timeout_usec;
long connection_timeout_sec;
long connection_timeout_usec;
char *default_username;
char *default_password;
/* Others */
long error_no;
char *error_msg;
ZEND_END_MODULE_GLOBALS(stomp)
#ifdef ZTS
#define STOMP_G(v) TSRMG(stomp_globals_id, zend_stomp_globals *, v)
#else
#define STOMP_G(v) (stomp_globals.v)
#endif
#endif /* PHP_STOMP_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
stomp-2.0.3/stomp.c 0000644 0001753 0001753 00000040601 14245353430 012336 0 ustar php php /*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Pierrick Charron |
+----------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "Zend/zend_smart_str.h"
#include "stomp.h"
#include "php_stomp.h"
#ifdef HAVE_NETINET_IN_H
#include
#endif
#define RETURN_READ_FRAME_FAIL { stomp_free_frame(f); return NULL; }
ZEND_EXTERN_MODULE_GLOBALS(stomp);
extern zend_class_entry *stomp_ce_exception;
/* {{{ DEBUG */
#if PHP_DEBUG
static void print_stomp_frame(stomp_frame_t *frame) {
php_printf("------ START FRAME ------\n");
php_printf("%s\n", frame->command);
/* Headers */
if (frame->headers) {
zend_string *key;
zval *value;
ZEND_HASH_FOREACH_STR_KEY_VAL(frame->headers, key, value) {
if (!key) {
break;
}
php_printf("%s:%s\n", ZSTR_VAL(key), Z_STRVAL_P(value));
} ZEND_HASH_FOREACH_END();
}
php_printf("\n%s\n", frame->body);
php_printf("------ END FRAME ------\n");
}
#endif
/* }}} */
/* {{{ stomp_init
*/
stomp_t *stomp_init()
{
/* Memory allocation */
stomp_t *stomp = (stomp_t *) emalloc(sizeof(stomp_t));
memset(stomp, 0, sizeof(*stomp));
/* Define all values */
stomp->host = NULL;
stomp->port = 0;
stomp->status = 0;
stomp->error = NULL;
stomp->error_details = NULL;
stomp->errnum = 0;
stomp->session = NULL;
stomp->options.connect_timeout_sec = 2;
stomp->options.connect_timeout_usec = 0;
stomp->options.read_timeout_sec = 2;
stomp->options.read_timeout_usec = 0;
#if HAVE_STOMP_SSL
stomp->options.use_ssl = 0;
stomp->ssl_handle = NULL;
#endif
stomp->frame_stack = NULL;
stomp->read_buffer.size = 0;
return stomp;
}
/* }}} */
/* {{{ stomp_frame_stack_push
*/
static void stomp_frame_stack_push(stomp_frame_stack_t **stack, stomp_frame_t *frame)
{
stomp_frame_stack_t *cell = (stomp_frame_stack_t *) emalloc(sizeof(stomp_frame_stack_t));
cell->frame = frame;
cell->next = NULL;
if (!*stack) {
*stack = cell;
} else {
stomp_frame_stack_t *cursor = *stack;
while (cursor->next != NULL) cursor = cursor->next;
cursor->next = cell;
}
}
/* }}} */
/* {{{ stomp_frame_stack_shift
*/
static stomp_frame_t *stomp_frame_stack_shift(stomp_frame_stack_t **stack) {
stomp_frame_t *frame = NULL;
if (*stack) {
stomp_frame_stack_t *cell = *stack;
*stack = cell->next;
frame = cell->frame;
efree(cell);
}
return frame;
}
/* }}} */
/* {{{ stomp_frame_stack_clear
*/
static void stomp_frame_stack_clear(stomp_frame_stack_t **stack) {
stomp_frame_t *frame = NULL;
while ((frame = stomp_frame_stack_shift(stack))) efree(frame);
}
/* }}} */
/* {{{ stomp_set_error
*/
void stomp_set_error(stomp_t *stomp, const char *error, int errnum, const char *fmt, ...)
{
va_list ap;
int len;
if (stomp->error != NULL) {
efree(stomp->error);
stomp->error = NULL;
}
if (stomp->error_details != NULL) {
efree(stomp->error_details);
stomp->error_details = NULL;
}
stomp->errnum = errnum;
if (error != NULL) {
stomp->error = estrdup(error);
}
if (fmt != NULL) {
stomp->error_details = emalloc(STOMP_BUFSIZE);
if (stomp->error_details == NULL) {
return; /* Nothing else can be done */
}
va_start(ap, fmt);
/*
* Would've been better to call vasprintf(), but that
* function is missing on some platforms...
*/
len = vsnprintf(stomp->error_details, STOMP_BUFSIZE, fmt, ap);
va_end(ap);
if (len < STOMP_BUFSIZE) {
stomp->error_details = erealloc(stomp->error_details, len+1);
}
}
}
/* }}} */
/* {{{ stomp_writable
*/
int stomp_writable(stomp_t *stomp)
{
int n;
n = php_pollfd_for_ms(stomp->fd, POLLOUT, 1000);
if (n != POLLOUT) {
#ifndef PHP_WIN32
if (n == 0) {
errno = ETIMEDOUT;
}
#endif
return 0;
}
return 1;
}
/* }}} */
/* {{{ stomp_connect
*/
int stomp_connect(stomp_t *stomp, const char *host, unsigned short port)
{
char error[1024];
socklen_t size;
struct timeval tv;
int flag = 1;
if (stomp->host != NULL) {
efree(stomp->host);
}
stomp->host = (char *) emalloc(strlen(host) + 1);
memcpy(stomp->host, host, strlen(host));
stomp->host[strlen(host)] = '\0';
stomp->port = port;
tv.tv_sec = stomp->options.connect_timeout_sec;
tv.tv_usec = stomp->options.connect_timeout_usec;
stomp->fd = php_network_connect_socket_to_host(stomp->host, stomp->port, SOCK_STREAM, 0, &tv, NULL, NULL, NULL, 0, 0);
if (stomp->fd == -1) {
snprintf(error, sizeof(error), "Unable to connect to %s:%d", stomp->host, stomp->port);
stomp_set_error(stomp, error, errno, "%s", strerror(errno));
return 0;
}
#ifdef HAVE_NETINET_IN_H
setsockopt(stomp->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
#endif
size = sizeof(stomp->localaddr);
memset(&stomp->localaddr, 0, size);
if (getsockname(stomp->fd, (struct sockaddr*) &stomp->localaddr, &size) == -1) {
snprintf(error, sizeof(error), "getsockname failed: %s (%d)", strerror(errno), errno);
stomp_set_error(stomp, error, errno, NULL);
return 0;
}
if (stomp_writable(stomp)) {
#if HAVE_STOMP_SSL
if (stomp->options.use_ssl) {
SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
int ret;
if (NULL == ctx) {
stomp_set_error(stomp, "failed to create the SSL context", 0, NULL);
return 0;
}
SSL_CTX_set_options(ctx, SSL_OP_ALL);
stomp->ssl_handle = SSL_new(ctx);
if (stomp->ssl_handle == NULL) {
stomp_set_error(stomp, "failed to create the SSL handle", 0, NULL);
SSL_CTX_free(ctx);
return 0;
}
SSL_set_fd(stomp->ssl_handle, stomp->fd);
if ((ret = SSL_connect(stomp->ssl_handle)) <= 0) {
stomp_set_error(stomp, "SSL/TLS handshake failed", 0, "SSL error %d", SSL_get_error(stomp->ssl_handle, ret));
SSL_shutdown(stomp->ssl_handle);
return 0;
}
}
#endif
return 1;
} else {
snprintf(error, sizeof(error), "Unable to connect to %s:%d", stomp->host, stomp->port);
stomp_set_error(stomp, error, errno, "%s", strerror(errno));
return 0;
}
}
/* }}} */
/* {{{ stomp_close
*/
void stomp_close(stomp_t *stomp)
{
if (NULL == stomp) {
return;
}
if (stomp->fd != -1) {
#if HAVE_STOMP_SSL
if(stomp->ssl_handle) {
SSL_shutdown(stomp->ssl_handle);
}
#endif
closesocket(stomp->fd);
}
if (stomp->host) {
efree(stomp->host);
}
if (stomp->session) {
efree(stomp->session);
}
if (stomp->error) {
efree(stomp->error);
}
if (stomp->error_details) {
efree(stomp->error_details);
}
stomp_frame_stack_clear(&stomp->frame_stack);
efree(stomp);
}
/* }}} */
/* {{{ stomp_send
*/
int stomp_send(stomp_t *stomp, stomp_frame_t *frame)
{
smart_str buf = {0};
/* Command */
smart_str_appends(&buf, frame->command);
smart_str_appendc(&buf, '\n');
/* Headers */
if (frame->headers) {
zend_string *key;
zval *value;
ZEND_HASH_FOREACH_STR_KEY_VAL(frame->headers, key, value) {
smart_str_appends(&buf, ZSTR_VAL(key));
smart_str_appendc(&buf, ':');
smart_str_appends(&buf, Z_STRVAL_P(value));
smart_str_appendc(&buf, '\n');
} ZEND_HASH_FOREACH_END();
}
if (frame->body_length > 0) {
smart_str_appendl(&buf, "content-length:", sizeof("content-length:") - 1);
smart_str_append_long(&buf, frame->body_length);
smart_str_appendc(&buf, '\n');
}
smart_str_appendc(&buf, '\n');
if (frame->body > 0) {
smart_str_appendl(&buf, frame->body, frame->body_length);
}
smart_str_appendl(&buf, "\0", sizeof("\0")-1);
if (!stomp_writable(stomp)) {
smart_str_free(&buf);
stomp_set_error(stomp, "Unable to send data", errno, "%s", strerror(errno));
return 0;
}
#ifdef HAVE_STOMP_SSL
if (stomp->options.use_ssl) {
int ret;
if (-1 == (ret = SSL_write(stomp->ssl_handle, ZSTR_VAL(buf.s), ZSTR_LEN(buf.s)))) {
smart_str_free(&buf);
stomp_set_error(stomp, "Unable to send data", errno, "SSL error %d", SSL_get_error(stomp->ssl_handle, ret));
return 0;
}
} else {
#endif
if (-1 == send(stomp->fd, ZSTR_VAL(buf.s), ZSTR_LEN(buf.s), 0)) {
smart_str_free(&buf);
stomp_set_error(stomp, "Unable to send data", errno, "%s", strerror(errno));
return 0;
}
#ifdef HAVE_STOMP_SSL
}
#endif
smart_str_free(&buf);
return 1;
}
/* }}} */
/* {{{ stomp_recv
*/
static int _stomp_recv(stomp_t *stomp, char *msg, const size_t length)
{
int len;
stomp_select(stomp);
#if HAVE_STOMP_SSL
if(stomp->options.use_ssl) {
len = SSL_read(stomp->ssl_handle, msg, length);
} else {
#endif
len = recv(stomp->fd, msg, length, 0);
#if HAVE_STOMP_SSL
}
#endif
if (len == -1) {
#if HAVE_STOMP_SSL
if (stomp->options.use_ssl) {
stomp_set_error(stomp, "Error reading from socket", errno, "%s. (SSL in use)", strerror(errno));
} else {
#endif
stomp_set_error(stomp, "Error reading from socket", errno, "%s. (SSL not in use)", strerror(errno));
#if HAVE_STOMP_SSL
}
#endif
stomp->status = -1;
} else if (len == 0) {
stomp_set_error(stomp, "Sender closed connection unexpectedly", 0, NULL);
stomp->status = -1;
}
return len;
}
int stomp_recv(stomp_t *stomp, char *msg, const size_t length)
{
if (stomp->read_buffer.size == 0) {
if (length >= STOMP_BUFSIZE) {
return _stomp_recv(stomp, msg, length);
} else {
size_t recv_size = _stomp_recv(stomp, stomp->read_buffer.buf, STOMP_BUFSIZE);
if (recv_size <= length) {
memcpy(msg, stomp->read_buffer.buf, recv_size);
return recv_size;
} else {
memcpy(msg, stomp->read_buffer.buf, length);
stomp->read_buffer.pos = stomp->read_buffer.buf + length;
stomp->read_buffer.size = recv_size - length;
return length;
}
}
} else if (stomp->read_buffer.size >= length) {
memcpy(msg, stomp->read_buffer.pos, length);
stomp->read_buffer.pos += length;
stomp->read_buffer.size -= length;
return length;
} else {
int len = stomp->read_buffer.size;
memcpy(msg, stomp->read_buffer.pos, stomp->read_buffer.size);
stomp->read_buffer.size = 0;
if (stomp_select_ex(stomp, 0, 0)) {
return len + stomp_recv(stomp, msg + len, length - len);
} else {
return len;
}
}
}
/* }}} */
/* {{{ _stomp_read_until
*/
static size_t _stomp_read_until(stomp_t *stomp, char **data, const char delimiter)
{
size_t length = 0;
size_t bufsize = STOMP_BUFSIZE;
char *buffer = (char *) emalloc(STOMP_BUFSIZE);
while (1) {
unsigned int i, found;
char *c;
found = 0;
// First populate the buffer
if (stomp->read_buffer.size == 0) {
stomp->read_buffer.size = _stomp_recv(stomp, stomp->read_buffer.buf, STOMP_BUFSIZE);
if (stomp->status == -1) {
length = 0;
break;
}
stomp->read_buffer.pos = stomp->read_buffer.buf;
}
// Then search the delimiter
c = stomp->read_buffer.pos;
for (i = 1; i <= stomp->read_buffer.size ; i++) {
if (*c == delimiter) {
found = 1;
break;
} else {
c++;
}
}
if (!found) i--;
// Make sure we have enough place in the buffer
if ((i+length) >= bufsize) {
buffer = (char *) erealloc(buffer, bufsize + STOMP_BUFSIZE);
bufsize += STOMP_BUFSIZE;
}
// Copy and update the buffer
memcpy(buffer + length, stomp->read_buffer.pos, i);
length += i;
stomp->read_buffer.pos += i;
stomp->read_buffer.size -= i;
if (found) {
break;
}
}
if (length) {
*data = buffer;
} else {
efree(buffer);
*data = NULL;
}
return length;
}
/* }}} */
/* {{{ stomp_read_buffer
*/
static size_t stomp_read_buffer(stomp_t *stomp, char **data)
{
size_t length = _stomp_read_until(stomp, data, 0);
if (stomp_select_ex(stomp, 0, 0)) {
char endline[1];
if (1 != stomp_recv(stomp, endline, 1) && '\n' != endline[0]) {
if (*data) {
efree(*data);
*data = NULL;
}
return 0;
}
}
if (length > 1) {
length --;
} else if (length) {
efree(*data);
*data = NULL;
length = 0;
}
return length;
}
/* }}} */
/* {{{ stomp_read_line
*/
static int stomp_read_line(stomp_t *stomp, char **data)
{
size_t length = _stomp_read_until(stomp, data, '\n');
if (length > 1) {
(*data)[length - 1] = 0;
length--;
} else if (length) {
efree(*data);
*data = NULL;
length = 0;
}
return length;
}
/* }}} */
/* {{{ stomp_free_frame
*/
void stomp_free_frame(stomp_frame_t *frame)
{
if (frame) {
if (frame->command) {
efree(frame->command);
}
if (frame->body) {
efree(frame->body);
}
if (frame->headers) {
zend_hash_destroy(frame->headers);
FREE_HASHTABLE(frame->headers);
}
efree(frame);
}
}
/* }}} */
/* {{{ stomp_read_frame
*/
stomp_frame_t *stomp_read_frame_ex(stomp_t *stomp, int use_stack)
{
stomp_frame_t *f = NULL;
char *cmd = NULL;
zval *length_str = NULL;
int length = 0;
if (use_stack && stomp->frame_stack) {
return stomp_frame_stack_shift(&stomp->frame_stack);
}
if (!stomp_select(stomp)) {
return NULL;
}
INIT_STOMP_FRAME(f);
if (NULL == f) {
return NULL;
}
/* Parse the command */
length = stomp_read_line(stomp, &cmd);
if (length < 1) {
RETURN_READ_FRAME_FAIL;
}
f->command = cmd;
f->command_length = length;
/* Parse the header */
while (1) {
char *p = NULL;
length = stomp_read_line(stomp, &p);
if (length < 0) {
RETURN_READ_FRAME_FAIL;
}
if (0 == length) {
break;
} else {
char *p2 = NULL;
char *key;
zval value;
p2 = strstr(p,":");
if (p2 == NULL) {
efree(p);
RETURN_READ_FRAME_FAIL;
}
/* Null terminate the key */
*p2 = 0;
key = p;
/* The rest is the value. */
ZVAL_STRING(&value, p2 + 1);
/* Insert key/value into hash table. */
zend_hash_str_add(f->headers, key, p2 - key, &value);
efree(p);
}
}
/* Check for the content length */
if ((length_str = zend_hash_str_find(f->headers, ZEND_STRL("content-length"))) != NULL) {
int recv_size = 0;
char endbuffer[2];
f->body_length = atoi(Z_STRVAL_P(length_str));
f->body = (char *) emalloc(f->body_length);
while (recv_size != f->body_length) {
int l = stomp_recv(stomp, f->body + recv_size, f->body_length - recv_size);
if (-1 == l) {
RETURN_READ_FRAME_FAIL;
} else {
recv_size += l;
}
}
length = stomp_recv(stomp, endbuffer, 2);
if (endbuffer[0] != '\0' || ((2 == length) && (endbuffer[1] != '\n'))) {
RETURN_READ_FRAME_FAIL;
}
} else {
f->body_length = stomp_read_buffer(stomp, &f->body);
}
return f;
}
/* }}} */
/* {{{ stomp_valid_receipt
*/
int stomp_valid_receipt(stomp_t *stomp, stomp_frame_t *frame) {
int success = 1;
zval *receipt;
if ((receipt = zend_hash_str_find(frame->headers, ZEND_STRL("receipt"))) != NULL) {
success = 0;
while (1) {
stomp_frame_t *res = stomp_read_frame_ex(stomp, 0);
if (res) {
if (0 == strncmp("RECEIPT", res->command, sizeof("RECEIPT") - 1)) {
zval *receipt_id;
if ((receipt_id = zend_hash_str_find(res->headers, ZEND_STRL("receipt-id"))) != NULL
&& zend_string_equals(Z_STR_P(receipt), Z_STR_P(receipt_id))) {
success = 1;
} else {
stomp_set_error(stomp, "Invalid receipt", 0, "%s", receipt_id);
}
stomp_free_frame(res);
return success;
} else if (0 == strncmp("ERROR", res->command, sizeof("ERROR") - 1)) {
zval *error_msg;
if ((error_msg = zend_hash_str_find(res->headers, ZEND_STRL("message"))) != NULL) {
stomp_set_error(stomp, Z_STRVAL_P(error_msg), 0, "%s", res->body);
}
stomp_free_frame(res);
return success;
} else {
stomp_frame_stack_push(&stomp->frame_stack, res);
}
} else {
return success;
}
}
}
return success;
}
/* }}} */
/* {{{ stomp_select
*/
int stomp_select_ex(stomp_t *stomp, const long int sec, const long int usec)
{
int n;
struct timeval tv;
if (stomp->read_buffer.size || stomp->frame_stack) {
return 1;
}
tv.tv_sec = sec;
tv.tv_usec = usec;
n = php_pollfd_for(stomp->fd, PHP_POLLREADABLE, &tv);
if (n < 1) {
#if !defined(PHP_WIN32) && !(defined(NETWARE) && defined(USE_WINSOCK))
if (n == 0) {
errno = ETIMEDOUT;
}
#endif
return 0;
}
return 1;
}
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
stomp-2.0.3/stomp.h 0000644 0001753 0001753 00000006011 14245353430 012340 0 ustar php php /*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Pierrick Charron |
+----------------------------------------------------------------------+
*/
#ifndef _STOMP_H_
#define _STOMP_H_
#include "php_network.h"
#if HAVE_STOMP_SSL
#include
#endif
#define STOMP_BUFSIZE 4096
#define INIT_STOMP_FRAME(f) \
f = (stomp_frame_t *) emalloc(sizeof(stomp_frame_t)); \
f->command = NULL; f->body = NULL; \
ALLOC_HASHTABLE(f->headers); \
zend_hash_init(f->headers, 0, NULL, ZVAL_PTR_DTOR, 0);
typedef struct _stomp_options {
long connect_timeout_sec;
long connect_timeout_usec;
long read_timeout_sec;
long read_timeout_usec;
#if HAVE_STOMP_SSL
int use_ssl;
#endif
} stomp_options_t;
typedef struct _stomp_frame {
char *command;
int command_length;
HashTable *headers;
char *body;
int body_length;
} stomp_frame_t;
typedef struct _stomp_frame_stack {
stomp_frame_t *frame;
struct _stomp_frame_stack *next;
} stomp_frame_stack_t;
typedef struct _stomp {
php_socket_t fd;
php_sockaddr_storage localaddr;
stomp_options_t options;
char *host;
unsigned short port;
int status;
char *error;
int errnum;
char *error_details;
char *session;
#if HAVE_STOMP_SSL
SSL *ssl_handle;
#endif
stomp_frame_stack_t *frame_stack;
struct {
size_t size;
char buf[STOMP_BUFSIZE];
char *pos;
} read_buffer;
} stomp_t;
stomp_t *stomp_init();
int stomp_connect(stomp_t *stomp, const char *host, unsigned short port);
void stomp_close(stomp_t *stomp);
int stomp_send(stomp_t *connection, stomp_frame_t *frame);
stomp_frame_t *stomp_read_frame_ex(stomp_t *connection, int use_stack);
int stomp_valid_receipt(stomp_t *connection, stomp_frame_t *frame);
int stomp_select_ex(stomp_t *connection, const long int sec, const long int usec);
void stomp_set_error(stomp_t *stomp, const char *error, int errnum, const char *fmt, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
void stomp_free_frame(stomp_frame_t *frame);
#define stomp_select(s) stomp_select_ex(s, s->options.read_timeout_sec, s->options.read_timeout_usec)
#define stomp_read_frame(c) stomp_read_frame_ex(c, 1)
#endif /* _STOMP_H_ */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
stomp-2.0.3/tests/config.inc 0000644 0001753 0001753 00000000211 14245353430 014123 0 ustar php php
stomp-2.0.3/tests/001-stomp.phpt 0000664 0001753 0001753 00000000303 14245353430 014524 0 ustar php php --TEST--
Check for stomp presence
--SKIPIF--
--FILE--
--EXPECT--
stomp extension is available
stomp-2.0.3/tests/002-version.phpt 0000644 0001753 0001753 00000000235 14245353430 015052 0 ustar php php --TEST--
Test stomp_version()
--SKIPIF--
--FILE--
--EXPECTF--
%d.%d.%s
stomp-2.0.3/tests/003-connect/001.phpt 0000644 0001753 0001753 00000001004 14245353430 015312 0 ustar php php --TEST--
Test stomp_connect() - URI validation
--SKIPIF--
--FILE--
--EXPECT--
NULL
string(18) "Invalid Broker URI"
NULL
string(18) "Invalid Broker URI"
NULL
string(18) "Invalid Broker URI"
NULL
string(25) "Invalid Broker URI scheme"
stomp-2.0.3/tests/003-connect/002.phpt 0000644 0001753 0001753 00000000507 14245353430 015322 0 ustar php php --TEST--
Test stomp_connect() - Test connection
--SKIPIF--
--FILE--
--EXPECTF--
resource(%d) of type (stomp connection)
NULL
stomp-2.0.3/tests/003-connect/003.phpt 0000644 0001753 0001753 00000000454 14245353430 015324 0 ustar php php --TEST--
Test stomp_connect() - Test error on CONNECT
--SKIPIF--
--FILE--
--EXPECTF--
string(14) "StompException"
stomp-2.0.3/tests/004-getSessionId/001.phpt 0000644 0001753 0001753 00000000444 14245353430 016271 0 ustar php php --TEST--
Test stomp_get_session_id()
--SKIPIF--
--FILE--
--EXPECTF--
string(%d) "%s"
stomp-2.0.3/tests/005-close/001.phpt 0000644 0001753 0001753 00000000376 14245353430 015003 0 ustar php php --TEST--
Test stomp_close() - tests parameters
--SKIPIF--
--FILE--
getMessage() . PHP_EOL;
}
?>
--EXPECTF--
%stomp_close()%s1%s null %s
stomp-2.0.3/tests/005-close/002.phpt 0000644 0001753 0001753 00000000474 14245353430 015003 0 ustar php php --TEST--
Test stomp_close()
--SKIPIF--
--FILE--
--EXPECT--
success
closed
stomp-2.0.3/tests/006-send/001.phpt 0000644 0001753 0001753 00000001317 14245353430 014624 0 ustar php php --TEST--
Test stomp_send() - tests parameters
--SKIPIF--
--FILE--
--EXPECTF--
Warning: stomp_send(): Destination can not be empty in %s on line %d
Warning: stomp_send(): Expects parameter %d to be a string or a StompFrame object. in %s on line %d
bool(true)
bool(true)
bool(true)
stomp-2.0.3/tests/006-send/002.phpt 0000644 0001753 0001753 00000001237 14245353430 014626 0 ustar php php --TEST--
Test stomp::send() - tests parameters
--SKIPIF--
--FILE--
send('', array());
$s->send('/queue/test-06', array());
var_dump($s->send('/queue/test-06', ''));
var_dump($s->send('/queue/test-06', 'A realMessage'));
var_dump($s->send('/queue/test-06', 'بياريك شارون'));
?>
--EXPECTF--
Warning: Stomp::send(): Destination can not be empty in %s on line %d
Warning: Stomp::send(): Expects parameter %d to be a string or a StompFrame object. in %s on line %d
bool(true)
bool(true)
bool(true)
stomp-2.0.3/tests/006-send/003.phpt 0000644 0001753 0001753 00000000536 14245353430 014630 0 ustar php php --TEST--
Test stomp::send() - test send with receipt
--SKIPIF--
--FILE--
send('/queue/test-06', 'A real message', array('receipt' => 'message-12345')));
?>
--EXPECTF--
bool(true)
stomp-2.0.3/tests/007-subscribe/001.phpt 0000644 0001753 0001753 00000001135 14245353430 015653 0 ustar php php --TEST--
Test Stomp::subscribe()
--SKIPIF--
--FILE--
subscribe('', array());
$s->subscribe('/queue/test', 'string');
?>
--EXPECTF--
Warning: Stomp::subscribe(): Destination can not be empty in %s007-subscribe%c001.php on line %d
Fatal error: Uncaught TypeError: %s, string given in %s007-subscribe%c001.php:%d
Stack trace:
#0 %s001.php(%d): Stomp->subscribe('/queue/test', 'string')
#1 {main}
thrown in %s007-subscribe%c001.php on line %d
stomp-2.0.3/tests/008-unsubscribe/001.phpt 0000644 0001753 0001753 00000001121 14245353430 016212 0 ustar php php --TEST--
Test Stomp::unsubscribe()
--SKIPIF--
--FILE--
unsubscribe('', array());
$s->unsubscribe('/queue/test', 'string');
?>
--EXPECTF--
Warning: Stomp::unsubscribe(): Destination can not be empty in %s008-unsubscribe%c001.php on line %d
Fatal error: Uncaught TypeError: %s2%s string given in %s008-unsubscribe%c001.php:%d
Stack trace:
#0 %s(%d): Stomp->unsubscribe('/queue/test', 'string')
#1 {main}
thrown in %s on line %d
stomp-2.0.3/tests/009-readFrame/001.phpt 0000644 0001753 0001753 00000000726 14245353430 015567 0 ustar php php --TEST--
Test stomp::readFrame() - tests functionnality and parameters
--SKIPIF--
--FILE--
send('/queue/test-09', 'A test Message');
$s->subscribe('/queue/test-09', array('ack' => 'auto'));
var_dump($s->readFrame()->body);
var_dump($s->readFrame());
?>
--EXPECTF--
string(14) "A test Message"
bool(false)
stomp-2.0.3/tests/009-readFrame/002.phpt 0000644 0001753 0001753 00000001022 14245353430 015556 0 ustar php php --TEST--
Test stomp_read_frame() - test functionnality and parameters
--SKIPIF--
--FILE--
'auto'));
$result = stomp_read_frame($link);
var_dump($result['body']);
var_dump(stomp_read_frame($link));
?>
--EXPECTF--
string(14) "A test Message"
bool(false)
stomp-2.0.3/tests/009-readFrame/003.phpt 0000644 0001753 0001753 00000001207 14245353430 015564 0 ustar php php --TEST--
Test stomp::readFrame() - custom frame class
--SKIPIF--
--FILE--
send('/queue/test-09', 'A test Message');
$s->subscribe('/queue/test-09', array('ack' => 'auto'));
$frame = $s->readFrame('customFrame');
var_dump(get_class($frame), $frame->body);
?>
--EXPECT--
string(11) "customFrame"
string(14) "A test Message"
stomp-2.0.3/tests/009-readFrame/004.phpt 0000644 0001753 0001753 00000000660 14245353430 015567 0 ustar php php --TEST--
Test stomp::readFrame() - Test the body binary safety
--SKIPIF--
--FILE--
send('/queue/test-09', "A test Message\0Foo");
$s->subscribe('/queue/test-09', array('ack' => 'auto'));
var_dump($s->readFrame()->body);
?>
--EXPECTF--
string(18) "A test Message Foo"
stomp-2.0.3/tests/009-readFrame/005.phpt 0000644 0001753 0001753 00000000746 14245353430 015575 0 ustar php php --TEST--
Test stomp_read_frame() - Test the body binary safety
--SKIPIF--
--FILE--
'auto'));
$result = stomp_read_frame($link);
var_dump($result['body']);
?>
--EXPECTF--
string(18) "A test Message Foo"
stomp-2.0.3/tests/009-readFrame/006.phpt 0000644 0001753 0001753 00000001406 14245353430 015570 0 ustar php php --TEST--
Test stomp::readFrame() - test frame stack
--SKIPIF--
--FILE--
subscribe('/queue/test-buffer', array('ack' => 'auto')));
var_dump($s->send('/queue/test-buffer', "Message1", array('receipt' => 'msg-1')));
var_dump($s->send('/queue/test-buffer', "Message2", array('receipt' => 'msg-2')));
var_dump($s->send('/queue/test-buffer', "Message3", array('receipt' => 'msg-3')));
var_dump($s->readFrame()->body);
var_dump($s->readFrame()->body);
var_dump($s->readFrame()->body);
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
bool(true)
string(8) "Message1"
string(8) "Message2"
string(8) "Message3"
stomp-2.0.3/tests/010-timeout/001.phpt 0000644 0001753 0001753 00000003665 14245353430 015364 0 ustar php php --TEST--
Test Stomp::getReadTimout() and Stomp::setReadTimeout() - tests functionnality and parameters
--INI--
stomp.default_read_timeout_sec=5
stomp.default_read_timeout_usec=5
--SKIPIF--
--FILE--
getReadTimeout());
// Set read timout with an integer as seconds
var_dump($s->setReadTimeout(10));
// Second test, read supposed to return 10.0
var_dump($s->getReadTimeout());
// Set read timout with an integer as seconds
var_dump($s->setReadTimeout(10, 5));
// Third test, read supposed to return 10.5
var_dump($s->getReadTimeout());
try {
// Set read timout with the first param as a string, supposed to trigger a warning/exception
var_dump($s->setReadTimeout(''));
} catch (TypeError $e) {
echo $e->getMessage() . PHP_EOL;
}
// Fourth test, read supposed to get the last value set : 10.5
var_dump($s->getReadTimeout());
try {
// Set read timout with the second param as a string, supposed to trigger a warning/exception
var_dump($s->setReadTimeout(10, ''));
} catch (TypeError $e) {
echo $e->getMessage() . PHP_EOL;
}
// Fourth test, read supposed to get the last value set : 10.5
var_dump($s->getReadTimeout());
// Set read timout with the params as null
var_dump($s->setReadTimeout(0, 0));
// Fifth test, read supposed to get the last value set : 0.0
var_dump($s->getReadTimeout());
unset($s);
?>
--EXPECTF--
array(2) {
["sec"]=>
int(5)
["usec"]=>
int(5)
}
NULL
array(2) {
["sec"]=>
int(10)
["usec"]=>
int(0)
}
NULL
array(2) {
["sec"]=>
int(10)
["usec"]=>
int(5)
}
%AStomp::setReadTimeout()%s1%s string given%A
array(2) {
["sec"]=>
int(10)
["usec"]=>
int(5)
}
%AStomp::setReadTimeout()%s2%s string given%A
array(2) {
["sec"]=>
int(10)
["usec"]=>
int(5)
}
NULL
array(2) {
["sec"]=>
int(0)
["usec"]=>
int(0)
}
stomp-2.0.3/tests/010-timeout/002.phpt 0000644 0001753 0001753 00000004206 14245353430 015355 0 ustar php php --TEST--
Test stomp_get_read_timout() and stomp_set_read_timeout() - tests functionnality and parameters
--INI--
stomp.default_read_timeout_sec=5
stomp.default_read_timeout_usec=5
--SKIPIF--
--FILE--
getMessage() . PHP_EOL;
}
// Fourth test, read supposed to get the last value set : 10.5
var_dump(stomp_get_read_timeout($link));
try {
// Set read timout with the second param as a string, supposed to trigger a warning on PHP 7
// supposed to trigger an exception on PHP 8
var_dump(stomp_set_read_timeout($link, 10, ''));
} catch (TypeError $e) {
echo $e->getMessage() . PHP_EOL;
}
// Fourth test, read supposed to get the last value set : 10.5
var_dump(stomp_get_read_timeout($link));
// Set read timout with the params as null
var_dump(stomp_set_read_timeout($link, 0, 0));
// Fifth test, read supposed to get the last value set : 0.0
var_dump(stomp_get_read_timeout($link));
unset($s);
?>
--EXPECTF--
array(2) {
["sec"]=>
int(5)
["usec"]=>
int(5)
}
NULL
array(2) {
["sec"]=>
int(10)
["usec"]=>
int(0)
}
NULL
array(2) {
["sec"]=>
int(10)
["usec"]=>
int(5)
}
%Astomp_set_read_timeout()%s2%S string given%A
array(2) {
["sec"]=>
int(10)
["usec"]=>
int(5)
}
%Astomp_set_read_timeout()%s3%s string given%A
array(2) {
["sec"]=>
int(10)
["usec"]=>
int(5)
}
NULL
array(2) {
["sec"]=>
int(0)
["usec"]=>
int(0)
}
stomp-2.0.3/tests/011-commit/001.phpt 0000644 0001753 0001753 00000002165 14245353430 015161 0 ustar php php --TEST--
Test Stomp::commit() - tests functionnality and parameters
--SKIPIF--
--FILE--
begin('t1'));
// sends a message to the queue and specifies a good transaction
var_dump($s->send('/queue/test-011-commit', 'bar', array('transaction' => 't1')));
// sends a message to the queue and asks for a receipt
$s->send('/queue/test-011-commit', 'bar', array('transaction' => 't2', 'receipt' => 'tptp'));
echo gettype($s->error()) . PHP_EOL;
// commits a valid transaction
var_dump($s->commit('t1'));
// commits non valid transaction (null as a parameter) and asks for a receipt
var_dump($s->commit(null, array('receipt' => 'commit-key')));
var_dump($s->commit(null));
// commits a non valid transaction (a transaction id that does not exist) and asks for a receipt
$s->commit('t2', array('receipt' => 'commit-key'));
echo gettype($s->error());
unset($s);
?>
--EXPECTF--
bool(true)
bool(true)
string
bool(true)
bool(false)
bool(true)
string
stomp-2.0.3/tests/bug_16930.phpt 0000644 0001753 0001753 00000000572 14245353430 014411 0 ustar php php --TEST--
Bug #16930 - readFrame reports error-frames as "timeout"
--SKIPIF--
--FILE--
abort('t2');
try {
var_dump($s->readFrame());
} catch(StompException $e) {
var_dump($e->getMessage());
}
?>
--EXPECTF--
string(%d) "%s"
stomp-2.0.3/tests/bug_16936.phpt 0000644 0001753 0001753 00000001506 14245353430 014415 0 ustar php php --TEST--
Bug #16936 - Module segfaults on readFrame if Frame > STOMP_BUFSIZE
--SKIPIF--
--FILE--
getMessage());
}
/* send a message to the queue 'foo' */
$stomp->send($queue, $msg);
/* subscribe to messages from the queue 'foo' */
$stomp->subscribe($queue, array('ack' => 'auto'));
/* read a frame */
$frame = $stomp->readFrame();
if ($frame->body === $msg) {
var_dump($frame->body);
/* acknowledge that the frame was received */
$stomp->ack($frame);
}
/* close connection */
unset($stomp);
?>
--EXPECTF--
string(%d) "%s"
stomp-2.0.3/doc/classes.php 0000644 0001753 0001753 00000010332 14245353430 013741 0 ustar php php send($queue, $msg);
$stomp->subscribe($queue);
$frame = $stomp->readFrame();
if ($frame->body === $msg) {
echo "Worked\n";
$stomp->ack($frame, array('receipt' => 'message-12345'));
} else {
echo "Failed\n";
}
$stomp->disconnect();
} catch(StompException $e) {
echo $e->getMessage();
}
stomp-2.0.3/examples/procedural.php 0000644 0001753 0001753 00000001013 14245353430 015511 0 ustar php php 't1'));
stomp_commit($stomp, 't1');
stomp_subscribe($stomp, $queue);
$frame = stomp_read_frame($stomp);
if ($frame['body'] === $msg) {
echo "Worked\n";
stomp_ack($stomp, $frame['headers']['message-id']);
} else {
echo "Failed\n";
}
stomp_close($stomp);
}