pax_global_header00006660000000000000000000000064121474571050014520gustar00rootroot0000000000000052 comment=432f1d361617550a2660d1b07089b971dd045a54 php-stomp-1.0.5/000077500000000000000000000000001214745710500134525ustar00rootroot00000000000000php-stomp-1.0.5/package.xml000066400000000000000000000240611214745710500155720ustar00rootroot00000000000000 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 2012-11-18 1.0.5 1.0.5 stable stable PHP License - 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) 5.2.2 1.4.0 openssl stomp 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) php-stomp-1.0.5/stomp-1.0.5/000077500000000000000000000000001214745710500152535ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/CREDITS000066400000000000000000000000271214745710500162720ustar00rootroot00000000000000stomp Pierrick Charron php-stomp-1.0.5/stomp-1.0.5/config.m4000066400000000000000000000015211214745710500167610ustar00rootroot00000000000000dnl $Id$ dnl config.m4 for extension stomp PHP_ARG_ENABLE(stomp, whether to enable stomp support, Make sure that the comment is aligned: [ --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 php-stomp-1.0.5/stomp-1.0.5/config.w32000066400000000000000000000004671214745710500170640ustar00rootroot00000000000000// $Id$ // 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"); } EXTENSION("stomp", "stomp.c php_stomp.c"); } php-stomp-1.0.5/stomp-1.0.5/doc/000077500000000000000000000000001214745710500160205ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/doc/classes.php000066400000000000000000000103721214745710500201710ustar00rootroot00000000000000send($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(); } php-stomp-1.0.5/stomp-1.0.5/examples/procedural.php000066400000000000000000000010141214745710500217360ustar00rootroot00000000000000 '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); } php-stomp-1.0.5/stomp-1.0.5/php_stomp.c000077500000000000000000001102711214745710500174350ustar00rootroot00000000000000/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2010 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 | +----------------------------------------------------------------------+ */ /* $Id$ */ #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 "ext/standard/php_smart_str.h" #define FETCH_STOMP_OBJECT \ i_obj = (stomp_object_t *) zend_object_store_get_object(stomp_object TSRMLS_CC); \ if (!(stomp = i_obj->stomp)) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, PHP_STOMP_ERR_NO_CTR); \ RETURN_FALSE; \ } #define INIT_FRAME_L(frame, cmd, l) \ frame.command = cmd; \ frame.command_length = l; \ ALLOC_HASHTABLE(frame.headers); \ zend_hash_init(frame.headers, 0, NULL, NULL, 0); #define INIT_FRAME(frame, cmd) INIT_FRAME_L(frame, cmd, sizeof(cmd)-1) #define FRAME_HEADER_FROM_HASHTABLE(h, p) \ HashTable *headers_ht = p; \ zval **value = NULL; \ char *string_key = NULL; \ ulong num_key; \ for (zend_hash_internal_pointer_reset(headers_ht); \ zend_hash_get_current_data(headers_ht, (void **)&value) == SUCCESS; \ zend_hash_move_forward(headers_ht)) { \ if (zend_hash_get_current_key(headers_ht, &string_key, &num_key, 1) != HASH_KEY_IS_STRING) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid argument or parameter array"); \ break; \ } else { \ if (Z_TYPE_PP(value) != IS_STRING) { \ SEPARATE_ZVAL(value); \ convert_to_string(*value); \ } \ zend_hash_add(h, string_key, strlen(string_key)+1, Z_STRVAL_PP(value), Z_STRLEN_PP(value)+1, NULL); \ efree(string_key); \ } \ } #define CLEAR_FRAME(frame) \ zend_hash_destroy(frame.headers); \ efree(frame.headers); #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 TSRMLS_CC, 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 = zend_throw_exception_ex(stomp_ce_exception, errno TSRMLS_CC, msg); \ if (details) { \ zend_update_property_string(stomp_ce_exception, object, "details", sizeof("details")-1, (char *) details TSRMLS_CC); \ } \ } static int le_stomp; 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_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_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(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 = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif PHP_STOMP_EXTNAME, stomp_functions, PHP_MINIT(stomp), PHP_MSHUTDOWN(stomp), PHP_RINIT(stomp), PHP_RSHUTDOWN(stomp), PHP_MINFO(stomp), #if ZEND_MODULE_API_NO >= 20010901 PHP_STOMP_VERSION, #endif 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_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->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 TSRMLS_DC) { stomp_frame_t frame = {0}; INIT_FRAME(frame, "DISCONNECT"); stomp_send(stomp, &frame TSRMLS_CC); CLEAR_FRAME(frame); } static void php_destroy_stomp_res(zend_rsrc_list_entry *rsrc TSRMLS_DC) { stomp_t *stomp = (stomp_t *) rsrc->ptr; stomp_send_disconnect(stomp TSRMLS_CC); stomp_close(stomp); } static void stomp_object_free_storage(stomp_object_t *intern TSRMLS_DC) { zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->stomp) { stomp_send_disconnect(intern->stomp TSRMLS_CC); stomp_close(intern->stomp); } efree(intern); } #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION > 5) #define PHP_STOMP_RUNTIME_CACHE #endif static zend_object_value php_stomp_new(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; stomp_object_t *intern; #ifndef PHP_STOMP_RUNTIME_CACHE zval *tmp; #endif intern = (stomp_object_t *) ecalloc(1, sizeof(stomp_object_t)); intern->stomp = NULL; zend_object_std_init(&intern->std, ce TSRMLS_CC); #ifdef PHP_STOMP_RUNTIME_CACHE object_properties_init(&intern->std, ce); #else zend_hash_copy(intern->std.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); #endif retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) stomp_object_free_storage, NULL TSRMLS_CC); retval.handlers = zend_get_std_object_handlers(); return retval; } /* }}} */ /* {{{ 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 TSRMLS_CC); stomp_ce_stomp->create_object = php_stomp_new; /* Register StompFrame class */ INIT_CLASS_ENTRY(ce, PHP_STOMP_FRAME_CLASSNAME, stomp_frame_methods); stomp_ce_frame = zend_register_internal_class(&ce TSRMLS_CC); /* Properties */ zend_declare_property_null(stomp_ce_frame, "command", sizeof("command")-1, ZEND_ACC_PUBLIC TSRMLS_CC); zend_declare_property_null(stomp_ce_frame, "headers", sizeof("headers")-1, ZEND_ACC_PUBLIC TSRMLS_CC); zend_declare_property_null(stomp_ce_frame, "body", sizeof("body")-1, ZEND_ACC_PUBLIC TSRMLS_CC); /* 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(TSRMLS_C), NULL TSRMLS_CC); /* Properties */ zend_declare_property_null(stomp_ce_exception, "details", sizeof("details")-1, ZEND_ACC_PRIVATE TSRMLS_CC); /** 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, 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; char *broker = NULL, *username = NULL, *password = NULL; int broker_len = 0, username_len = 0, password_len = 0; php_url *url_parts; #ifdef HAVE_STOMP_SSL int use_ssl = 0; #endif if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sssa!", &broker, &broker_len, &username, &username_len, &password, &password_len, &headers) == FAILURE) { return; } /* Verify that broker URI */ if (!broker) { broker = STOMP_G(default_broker); } url_parts = php_url_parse_ex(broker, strlen(broker)); if (!url_parts || !url_parts->host) { STOMP_ERROR(0, PHP_STOMP_ERR_INVALID_BROKER_URI); php_url_free(url_parts); return; } if (url_parts->scheme) { if (strcmp(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(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, url_parts->host, url_parts->port ? url_parts->port : 61613 TSRMLS_CC); php_url_free(url_parts); if (stomp->status) { stomp_frame_t *res; stomp_frame_t frame = {0}; INIT_FRAME(frame, "CONNECT"); if (username_len == 0) { username = ""; } if (password_len == 0) { password = ""; } zend_hash_add(frame.headers, "login", sizeof("login"), username, username_len + 1, NULL); zend_hash_add(frame.headers, "passcode", sizeof("passcode"), password, password_len + 1, NULL); if (NULL != headers) { FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(headers)); } stomp_send(stomp, &frame TSRMLS_CC); CLEAR_FRAME(frame); /* Retreive Response */ res = stomp_read_frame(stomp); if (NULL == res) { STOMP_ERROR(0, PHP_STOMP_ERR_SERVER_NOT_RESPONDING); } 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); } } else { char *key = NULL; if (zend_hash_find(res->headers, "session", sizeof("session"), (void **)&key) == SUCCESS) { if (stomp->session) { efree(stomp->session); } stomp->session = estrdup(key); } stomp_free_frame(res); if (!stomp_object) { ZEND_REGISTER_RESOURCE(return_value, stomp, le_stomp); return; } else { stomp_object_t *i_obj = (stomp_object_t *) zend_object_store_get_object(stomp_object TSRMLS_CC); 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),1); } 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) { stomp_object_t *i_obj = NULL; FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } if (!stomp) { php_error_docref(NULL TSRMLS_CC, E_WARNING, PHP_STOMP_ERR_NO_CTR); RETURN_FALSE; } if (stomp->session) { RETURN_STRING(stomp->session, 1); } 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 = NULL; FETCH_STOMP_OBJECT; stomp_send_disconnect(stomp TSRMLS_CC); stomp_close(stomp); i_obj->stomp = NULL; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); zend_list_delete(Z_RESVAL_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; char *destination = NULL; int destination_length = 0; zval *msg = NULL, *headers = NULL; stomp_frame_t frame = {0}; int success = 0; if (stomp_object) { stomp_object_t *i_obj = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|a!", &destination, &destination_length, &msg, &headers) == FAILURE) { return; } FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|a!", &arg, &destination, &destination_length, &msg, &headers) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } /* Verify destination */ if (0 == destination_length) { php_error_docref(NULL TSRMLS_CC, 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 */ zend_hash_add(frame.headers, "destination", sizeof("destination"), destination, destination_length + 1, NULL); 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 TSRMLS_CC)) { zval *frame_obj_prop = NULL; frame_obj_prop = zend_read_property(stomp_ce_frame, msg, "command", sizeof("command")-1, 1 TSRMLS_CC); 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, msg, "body", sizeof("body")-1, 1 TSRMLS_CC); 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, msg, "headers", sizeof("headers")-1, 1 TSRMLS_CC); 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 TSRMLS_CC, 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 TSRMLS_CC) > 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; char *destination = NULL; int destination_length = 0; zval *headers = NULL; stomp_frame_t frame = {0}; int success = 0; if (stomp_object) { stomp_object_t *i_obj = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a!", &destination, &destination_length, &headers) == FAILURE) { return; } FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|a!", &arg, &destination, &destination_length, &headers) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } /* Verify destination */ if (0 == destination_length) { php_error_docref(NULL TSRMLS_CC, 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 destination */ zend_hash_add(frame.headers, "ack", sizeof("ack"), "client", sizeof("client"), NULL); zend_hash_add(frame.headers, "destination", sizeof("destination"), destination, destination_length + 1, NULL); zend_hash_add(frame.headers, "activemq.prefetchSize", sizeof("activemq.prefetchSize"), "1", sizeof("1"), NULL); if (stomp_send(stomp, &frame TSRMLS_CC) > 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; char *destination = NULL; int destination_length = 0; zval *headers = NULL; stomp_frame_t frame = {0}; int success = 0; if (stomp_object) { stomp_object_t *i_obj = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a!", &destination, &destination_length, &headers) == FAILURE) { return; } FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|a!", &arg, &destination, &destination_length, &headers) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } /* Verify destination */ if (0 == destination_length) { php_error_docref(NULL TSRMLS_CC, 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 */ zend_hash_add(frame.headers, "destination", sizeof("destination"), destination, destination_length + 1, NULL); if (stomp_send(stomp, &frame TSRMLS_CC) > 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) { stomp_object_t *i_obj = NULL; FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } 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; char *class_name = NULL; int class_name_len = 0; zend_class_entry *ce = NULL; if (stomp_object) { stomp_object_t *i_obj = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &class_name, &class_name_len) == FAILURE) { return; } FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s", &arg, &class_name, &class_name_len) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } if (class_name_len > 0) { ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); if (!ce) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name); ce = stomp_ce_frame; } } else if (stomp_object) { ce = stomp_ce_frame; } if ((res = stomp_read_frame(stomp))) { zval *headers = NULL; if (0 == strncmp("ERROR", res->command, sizeof("ERROR") - 1)) { char *error_msg = NULL; if (zend_hash_find(res->headers, "message", sizeof("message"), (void **)&error_msg) == SUCCESS) { zval *excobj = zend_throw_exception_ex(stomp_ce_exception, 0 TSRMLS_CC, error_msg); if (res->body) { zend_update_property_string(stomp_ce_exception, excobj, "details", sizeof("details")-1, (char *) res->body TSRMLS_CC); } stomp_free_frame(res); RETURN_FALSE; } } MAKE_STD_ZVAL(headers); array_init(headers); if (res->headers) { char *key; ulong pos; zend_hash_internal_pointer_reset(res->headers); while (zend_hash_get_current_key(res->headers, &key, &pos, 0) == HASH_KEY_IS_STRING) { char *value = NULL; if (zend_hash_get_current_data(res->headers, (void **)&value) == SUCCESS) { add_assoc_string(headers, key, value, 1); } zend_hash_move_forward(res->headers); } } if (ce) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval *retval_ptr; object_init_ex(return_value, ce); if (ce->constructor) { zval *cmd = NULL, *body = NULL; ALLOC_ZVAL(cmd); #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) Z_SET_REFCOUNT_P(cmd, 1); Z_UNSET_ISREF_P(cmd); #else cmd->refcount = 1; cmd->is_ref = 0; #endif ZVAL_STRINGL(cmd, res->command, res->command_length, 1); ALLOC_ZVAL(body); #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) Z_SET_REFCOUNT_P(body, 1); Z_UNSET_ISREF_P(body); #else body->refcount = 1; body->is_ref = 0; #endif if (res->body) { ZVAL_STRINGL(body, res->body, res->body_length, 1); } else { ZVAL_NULL(body); } fci.size = sizeof(fci); fci.function_table = &ce->function_table; fci.function_name = NULL; fci.symbol_table = NULL; #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) fci.object_ptr = return_value; #else fci.object_pp = &return_value; #endif fci.retval_ptr_ptr = &retval_ptr; // PARAMS fci.param_count = 3; fci.params = (zval***) safe_emalloc(sizeof(zval*), 3, 0); fci.params[0] = &cmd; fci.params[1] = &headers; fci.params[2] = &body; fci.no_separation = 1; fcc.initialized = 1; fcc.function_handler = ce->constructor; fcc.calling_scope = EG(scope); #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) fcc.called_scope = Z_OBJCE_P(return_value); fcc.object_ptr = return_value; #else fcc.object_pp = &return_value; #endif if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); } else { if (retval_ptr) { zval_ptr_dtor(&retval_ptr); } } 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"), res->command, 1); if (res->body) { add_assoc_stringl_ex(return_value, "body", sizeof("body"), res->body, res->body_length, 1); } add_assoc_zval_ex(return_value, "headers", sizeof("headers"), headers); } stomp_free_frame(res); } else { RETURN_FALSE; } } /* }}} */ /* {{{ _php_stomp_transaction */ static void _php_stomp_transaction(INTERNAL_FUNCTION_PARAMETERS, char *cmd) { zval *stomp_object = getThis(); stomp_t *stomp = NULL; char *transaction_id = NULL; int transaction_id_length = 0; stomp_frame_t frame = {0}; int success = 0; zval *headers = NULL; if (stomp_object) { stomp_object_t *i_obj = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &transaction_id, &transaction_id_length, &headers) == FAILURE) { return; } FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|a", &arg, &transaction_id, &transaction_id_length, &headers) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } INIT_FRAME_L(frame, cmd, strlen(cmd)); if (transaction_id_length > 0) { zend_hash_add(frame.headers, "transaction", sizeof("transaction"), transaction_id, transaction_id_length + 1, NULL); } /* 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 TSRMLS_CC) > 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"); } /* }}} */ /* {{{ 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"); } /* }}} */ /* {{{ 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"); } /* }}} */ /* {{{ proto boolean Stomp::ack(mixed msg [, array headers]) Acknowledge consumption of a message from a subscription using client acknowledgment */ PHP_FUNCTION(stomp_ack) { zval *stomp_object = getThis(); zval *msg = NULL, *headers = NULL; stomp_t *stomp = NULL; stomp_frame_t frame = {0}; int success = 0; if (stomp_object) { stomp_object_t *i_obj = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a!", &msg, &headers) == FAILURE) { return; } FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|a!", &arg, &msg, &headers) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } INIT_FRAME(frame, "ACK"); if (NULL != headers) { FRAME_HEADER_FROM_HASHTABLE(frame.headers, Z_ARRVAL_P(headers)); } if (Z_TYPE_P(msg) == IS_STRING) { zend_hash_add(frame.headers, "message-id", sizeof("message-id"), Z_STRVAL_P(msg), Z_STRLEN_P(msg) + 1, NULL); } else if (Z_TYPE_P(msg) == IS_OBJECT && instanceof_function(Z_OBJCE_P(msg), stomp_ce_frame TSRMLS_CC)) { zval *frame_obj_prop = zend_read_property(stomp_ce_frame, msg, "headers", sizeof("headers")-1, 1 TSRMLS_CC); 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 TSRMLS_CC, 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 TSRMLS_CC) > 0) { success = stomp_valid_receipt(stomp, &frame); } CLEAR_FRAME(frame); RETURN_BOOL(success); } /* }}} */ /* {{{ proto string Stomp::error() Get the last error message */ PHP_FUNCTION(stomp_error) { zval *stomp_object = getThis(); stomp_t *stomp = NULL; if (stomp_object) { stomp_object_t *i_obj = NULL; FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } 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); RETURN_STRING(error_msg, 0); } else { RETURN_STRING(stomp->error, 1); } } 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; long sec = 0, usec = 0; if (stomp_object) { stomp_object_t *i_obj = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &sec, &usec) == FAILURE) { return; } FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &arg, &sec, &usec) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } 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) { stomp_object_t *i_obj = NULL; FETCH_STOMP_OBJECT; } else { zval *arg = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg) == FAILURE) { return; } ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp); } array_init(return_value); add_assoc_long_ex(return_value, "sec", sizeof("sec"), stomp->options.read_timeout_sec); add_assoc_long_ex(return_value, "usec", sizeof("usec"), 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; int command_length = 0, body_length = -1; zval *headers = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sa!s", &command, &command_length, &headers, &body, &body_length) == FAILURE) { return; } if (command_length > 0) { zend_update_property_stringl(stomp_ce_frame, object, "command", sizeof("command")-1, command, command_length TSRMLS_CC); } if (headers) { zend_update_property(stomp_ce_frame, object, "headers", sizeof("headers")-1, headers TSRMLS_CC); } if (body_length > 0) { zend_update_property_stringl(stomp_ce_frame, object, "body", sizeof("body")-1, body, body_length TSRMLS_CC); } } /* }}} */ /* {{{ proto string StompException::getDetails() Get error details */ PHP_METHOD(stompexception, getDetails) { zval *object = getThis(); zval *details = NULL; details = zend_read_property(stomp_ce_exception, object, "details", sizeof("details")-1, 1 TSRMLS_CC); RETURN_STRINGL(Z_STRVAL_P(details), Z_STRLEN_P(details), 1); } /* }}} */ php-stomp-1.0.5/stomp-1.0.5/php_stomp.h000066400000000000000000000075671214745710500174540ustar00rootroot00000000000000/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2010 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 | +----------------------------------------------------------------------+ */ /* $Id$ */ #ifndef PHP_STOMP_H #define PHP_STOMP_H #include "stomp.h" typedef struct _stomp_object { zend_object std; stomp_t *stomp; } stomp_object_t; #define PHP_STOMP_EXTNAME "Stomp" #define PHP_STOMP_MAJOR_VERSION "1" #define PHP_STOMP_MINOR_VERSION "0" #define PHP_STOMP_PATCH_VERSION "5" #define PHP_STOMP_VERSION_STATUS "" #define PHP_STOMP_VERSION PHP_STOMP_MAJOR_VERSION "." PHP_STOMP_MINOR_VERSION "." PHP_STOMP_PATCH_VERSION PHP_STOMP_VERSION_STATUS #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_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; /* 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 */ php-stomp-1.0.5/stomp-1.0.5/stomp.c000066400000000000000000000336441214745710500165730ustar00rootroot00000000000000/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2010 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 | +----------------------------------------------------------------------+ */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "zend_exceptions.h" #include "ext/standard/php_smart_str.h" #include "stomp.h" #include "php_stomp.h" #define RETURN_READ_FRAME_FAIL { stomp_free_frame(f); return NULL; } ZEND_EXTERN_MODULE_GLOBALS(stomp); extern zend_class_entry *stomp_ce_exception; /* {{{ 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->buffer = NULL; return stomp; } /* }}} */ /* {{{ stomp_frame_buffer_push */ void stomp_frame_buffer_push(stomp_frame_cell_t **pcell, stomp_frame_t *frame) { stomp_frame_cell_t *cell = (stomp_frame_cell_t *) emalloc(sizeof(stomp_frame_cell_t)); cell->frame = frame; cell->next = NULL; if (!*pcell) { *pcell = cell; } else { stomp_frame_cell_t *cursor = *pcell; while (cursor->next != NULL) cursor = cursor->next; cursor->next = cell; } } /* }}} */ /* {{{ stomp_frame_buffer_shift */ stomp_frame_t *stomp_frame_buffer_shift(stomp_frame_cell_t **pcell) { stomp_frame_t *frame = NULL; if (*pcell) { stomp_frame_cell_t *cell = *pcell; *pcell = cell->next; frame = cell->frame; efree(cell); } return frame; } /* }}} */ /* {{{ stomp_frame_buffer_clear */ void stomp_frame_buffer_clear(stomp_frame_cell_t **pcell) { stomp_frame_t *frame = NULL; while (frame = stomp_frame_buffer_shift(pcell)) efree(frame); } /* }}} */ /* {{{ stomp_set_error */ void stomp_set_error(stomp_t *stomp, const char *error, int errnum, const char *details) { 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 (details != NULL) { stomp->error_details = estrdup(details); } } /* }}} */ /* {{{ stomp_writeable */ int stomp_writeable(stomp_t *stomp) { int n; n = php_pollfd_for_ms(stomp->fd, POLLOUT, 1000); if (n < 1) { #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 TSRMLS_DC) { char error[1024]; socklen_t size; struct timeval tv; 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 TSRMLS_CC); if (stomp->fd == -1) { snprintf(error, sizeof(error), "Unable to connect to %s:%ld", stomp->host, stomp->port); stomp_set_error(stomp, error, errno, NULL); return 0; } 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_writeable(stomp)) { #if HAVE_STOMP_SSL if (stomp->options.use_ssl) { SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); 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 (SSL_connect(stomp->ssl_handle) <= 0) { stomp_set_error(stomp, "SSL/TLS handshake failed", 0, NULL); SSL_shutdown(stomp->ssl_handle); return 0; } } #endif return 1; } else { snprintf(error, sizeof(error), "Unable to connect to %s:%ld", stomp->host, stomp->port); stomp_set_error(stomp, error, errno, NULL); 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_buffer_clear(&stomp->buffer); efree(stomp); } /* }}} */ /* {{{ stomp_send */ int stomp_send(stomp_t *stomp, stomp_frame_t *frame TSRMLS_DC) { smart_str buf = {0}; /* Command */ smart_str_appends(&buf, frame->command); smart_str_appendc(&buf, '\n'); /* Headers */ if (frame->headers) { char *key; ulong pos; zend_hash_internal_pointer_reset(frame->headers); while (zend_hash_get_current_key(frame->headers, &key, &pos, 0) == HASH_KEY_IS_STRING) { char *value = NULL; smart_str_appends(&buf, key); smart_str_appendc(&buf, ':'); if (zend_hash_get_current_data(frame->headers, (void **)&value) == SUCCESS) { smart_str_appends(&buf, value); } smart_str_appendc(&buf, '\n'); zend_hash_move_forward(frame->headers); } } if (frame->body_length > 0) { smart_str_appends(&buf, "content-length:"); 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 > 0 ? frame->body_length : strlen(frame->body)); } if (!stomp_writeable(stomp)) { char error[1024]; snprintf(error, sizeof(error), "Unable to send data"); stomp_set_error(stomp, error, errno, NULL); smart_str_free(&buf); return 0; } #ifdef HAVE_STOMP_SSL if (stomp->options.use_ssl) { if (-1 == SSL_write(stomp->ssl_handle, buf.c, buf.len) || -1 == SSL_write(stomp->ssl_handle, "\0\n", 2)) { char error[1024]; snprintf(error, sizeof(error), "Unable to send data"); stomp_set_error(stomp, error, errno, NULL); smart_str_free(&buf); return 0; } } else { #endif if (-1 == send(stomp->fd, buf.c, buf.len, 0) || -1 == send(stomp->fd, "\0\n", 2, 0)) { char error[1024]; snprintf(error, sizeof(error), "Unable to send data"); stomp_set_error(stomp, error, errno, NULL); smart_str_free(&buf); return 0; } #ifdef HAVE_STOMP_SSL } #endif smart_str_free(&buf); return 1; } /* }}} */ /* {{{ stomp_recv */ int stomp_recv(stomp_t *stomp, char *msg, size_t length) { int len; #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 == 0) { TSRMLS_FETCH(); zend_throw_exception_ex(stomp_ce_exception, errno TSRMLS_CC, "Unexpected EOF while reading from socket"); stomp->status = -1; } return len; } /* }}} */ /* {{{ stomp_read_buffer */ static int stomp_read_buffer(stomp_t *stomp, char **data) { int rc = 0; size_t i = 0; size_t bufsize = STOMP_BUFSIZE + 1; char *buffer = (char *) emalloc(STOMP_BUFSIZE + 1); while (1) { size_t length = 1; rc = stomp_recv(stomp, buffer + i, length); if (rc < 1) { efree(buffer); return -1; } if (1 == length) { i++; if (buffer[i-1] == 0) { char endline[1]; if (1 != stomp_recv(stomp, endline, 1) && '\n' != endline[0]) { efree(buffer); return 0; } break; } if (i >= bufsize) { buffer = (char *) erealloc(buffer, bufsize + STOMP_BUFSIZE); bufsize += STOMP_BUFSIZE; } } } if (i > 1) { *data = (char *) emalloc(i); if (NULL == *data) { efree(buffer); return -1; } memcpy(*data, buffer, i); } efree(buffer); return i-1; } /* }}} */ /* {{{ stomp_read_line */ static int stomp_read_line(stomp_t *stomp, char **data) { int rc = 0; size_t i = 0; size_t bufsize = STOMP_BUFSIZE + 1; char *buffer = (char *) emalloc(STOMP_BUFSIZE + 1); while (1) { size_t length = 1; rc = stomp_recv(stomp, buffer + i, length); if (rc < 1) { efree(buffer); return -1; } if (1 == length) { i++; if (buffer[i-1] == '\n') { buffer[i-1] = 0; break; } else if (buffer[i-1] == 0) { efree(buffer); return 0; } if (i >= bufsize) { buffer = (char *) erealloc(buffer, bufsize + STOMP_BUFSIZE); bufsize += STOMP_BUFSIZE; } } } if (i > 1) { *data = (char *) emalloc(i); if (NULL == *data) { efree(buffer); return -1; } memcpy(*data, buffer, i); } efree(buffer); return i-1; } /* }}} */ /* {{{ 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); efree(frame->headers); } efree(frame); } } /* }}} */ /* {{{ stomp_read_frame */ stomp_frame_t *stomp_read_frame(stomp_t *stomp) { stomp_frame_t *f = NULL; char *cmd = NULL, *length_str = NULL; int length = 0; if (stomp->buffer) { return stomp_frame_buffer_shift(&stomp->buffer); } 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; char *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. */ value = p2+1; /* Insert key/value into hash table. */ zend_hash_add(f->headers, key, strlen(key) + 1, value, strlen(value) + 1, NULL); efree(p); } } /* Check for the content length */ if (zend_hash_find(f->headers, "content-length", sizeof("content-length"), (void **)&length_str) == SUCCESS) { char endbuffer[2]; length = 2; f->body_length = atoi(length_str); f->body = (char *) emalloc(f->body_length); if (-1 == stomp_recv(stomp, f->body, f->body_length)) { RETURN_READ_FRAME_FAIL; } if (length != stomp_recv(stomp, endbuffer, length) || endbuffer[0] != '\0' || 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; char error[1024]; char *receipt = NULL; if (zend_hash_find(frame->headers, "receipt", sizeof("receipt"), (void **)&receipt) == SUCCESS) { stomp_frame_cell_t *buffer = NULL; success = 0; while (1) { stomp_frame_t *res = stomp_read_frame(stomp); if (res) { if (0 == strncmp("RECEIPT", res->command, sizeof("RECEIPT") - 1)) { char *receipt_id = NULL; if (zend_hash_find(res->headers, "receipt-id", sizeof("receipt-id"), (void **)&receipt_id) == SUCCESS && strlen(receipt) == strlen(receipt_id) && !strcmp(receipt, receipt_id)) { success = 1; } else { snprintf(error, sizeof(error), "Unexpected receipt id : %s", receipt_id); stomp_set_error(stomp, error, 0, NULL); } stomp_free_frame(res); stomp->buffer = buffer; return success; } else if (0 == strncmp("ERROR", res->command, sizeof("ERROR") - 1)) { char *error_msg = NULL; if (zend_hash_find(res->headers, "message", sizeof("message"), (void **)&error_msg) == SUCCESS) { stomp_set_error(stomp, error_msg, 0, res->body); } stomp_free_frame(res); stomp->buffer = buffer; return success; } else { stomp_frame_buffer_push(&buffer, res); } } else { stomp->buffer = buffer; return success; } } } return success; } /* }}} */ /* {{{ stomp_select */ int stomp_select(stomp_t *stomp) { int n; struct timeval tv; if (stomp->buffer) { return 1; } tv.tv_sec = stomp->options.read_timeout_sec; tv.tv_usec = stomp->options.read_timeout_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; } /* }}} */ php-stomp-1.0.5/stomp-1.0.5/stomp.h000077500000000000000000000055401214745710500165750ustar00rootroot00000000000000/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2010 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 | +----------------------------------------------------------------------+ */ /* $Id$ */ #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, NULL, 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_cell { stomp_frame_t *frame; struct _stomp_frame_cell *next; } stomp_frame_cell_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_cell_t *buffer; } stomp_t; stomp_t *stomp_init(); int stomp_connect(stomp_t *stomp, const char *host, unsigned short port TSRMLS_DC); void stomp_close(stomp_t *stomp); int stomp_send(stomp_t *connection, stomp_frame_t *frame TSRMLS_DC); stomp_frame_t *stomp_read_frame(stomp_t *connection); int stomp_valid_receipt(stomp_t *connection, stomp_frame_t *frame); int stomp_select(stomp_t *connection); void stomp_set_error(stomp_t *stomp, const char *error, int errnum, const char *details); void stomp_free_frame(stomp_frame_t *frame); #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 */ php-stomp-1.0.5/stomp-1.0.5/tests/000077500000000000000000000000001214745710500164155ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/001-stomp.phpt000066400000000000000000000003031214745710500207460ustar00rootroot00000000000000--TEST-- Check for stomp presence --SKIPIF-- --FILE-- --EXPECT-- stomp extension is available php-stomp-1.0.5/stomp-1.0.5/tests/002-version.phpt000066400000000000000000000002361214745710500212770ustar00rootroot00000000000000--TEST-- Test stomp_version() --SKIPIF-- --FILE-- --EXPECTF-- %d.%d.%s php-stomp-1.0.5/stomp-1.0.5/tests/003-connect/000077500000000000000000000000001214745710500203465ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/003-connect/001.phpt000066400000000000000000000010051214745710500215370ustar00rootroot00000000000000--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" php-stomp-1.0.5/stomp-1.0.5/tests/003-connect/002.phpt000066400000000000000000000003731214745710500215470ustar00rootroot00000000000000--TEST-- Test stomp_connect() - Test connection --SKIPIF-- --FILE-- --EXPECTF-- resource(%d) of type (stomp connection) NULL php-stomp-1.0.5/stomp-1.0.5/tests/004-getSessionId/000077500000000000000000000000001214745710500213165ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/004-getSessionId/001.phpt000066400000000000000000000004041214745710500225110ustar00rootroot00000000000000--TEST-- Test stomp_get_session_id() --SKIPIF-- --FILE-- --EXPECTF-- string(%d) "%s" php-stomp-1.0.5/stomp-1.0.5/tests/005-close/000077500000000000000000000000001214745710500200245ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/005-close/001.phpt000066400000000000000000000004001214745710500212130ustar00rootroot00000000000000--TEST-- Test stomp_close() - tests parameters --SKIPIF-- --FILE-- --EXPECTF-- Warning: stomp_close() expects parameter 1 to be resource, null given in %s on line %d php-stomp-1.0.5/stomp-1.0.5/tests/005-close/002.phpt000066400000000000000000000004341214745710500212230ustar00rootroot00000000000000--TEST-- Test stomp_close() --SKIPIF-- --FILE-- --EXPECT-- success closed php-stomp-1.0.5/stomp-1.0.5/tests/006-send/000077500000000000000000000000001214745710500176515ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/006-send/001.phpt000066400000000000000000000012551214745710500210510ustar00rootroot00000000000000--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) php-stomp-1.0.5/stomp-1.0.5/tests/006-send/002.phpt000066400000000000000000000011741214745710500210520ustar00rootroot00000000000000--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) php-stomp-1.0.5/stomp-1.0.5/tests/007-subscribe/000077500000000000000000000000001214745710500207025ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/007-subscribe/001.phpt000066400000000000000000000007011214745710500220750ustar00rootroot00000000000000--TEST-- Test Stomp::subscribe() --SKIPIF-- --FILE-- subscribe('', array()); $s->subscribe('/queue/test', 'string'); ?> --EXPECTF-- Warning: Stomp::subscribe(): Destination can not be empty in %s on line %d Catchable fatal error: Argument 2 passed to Stomp::subscribe() must be %s array, string given in %s on line %d php-stomp-1.0.5/stomp-1.0.5/tests/008-unsubscribe/000077500000000000000000000000001214745710500212465ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/008-unsubscribe/001.phpt000066400000000000000000000007131214745710500224440ustar00rootroot00000000000000--TEST-- Test Stomp::unsubscribe() --SKIPIF-- --FILE-- unsubscribe('', array()); $s->unsubscribe('/queue/test', 'string'); ?> --EXPECTF-- Warning: Stomp::unsubscribe(): Destination can not be empty in %s on line %d Catchable fatal error: Argument 2 passed to Stomp::unsubscribe() must be %s array, string given in %s on line %d php-stomp-1.0.5/stomp-1.0.5/tests/009-readFrame/000077500000000000000000000000001214745710500206115ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/009-readFrame/001.phpt000066400000000000000000000006631214745710500220130ustar00rootroot00000000000000--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) php-stomp-1.0.5/stomp-1.0.5/tests/009-readFrame/002.phpt000066400000000000000000000007561214745710500220170ustar00rootroot00000000000000--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) php-stomp-1.0.5/stomp-1.0.5/tests/009-readFrame/003.phpt000066400000000000000000000011461214745710500220120ustar00rootroot00000000000000--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" php-stomp-1.0.5/stomp-1.0.5/tests/009-readFrame/004.phpt000066400000000000000000000006151214745710500220130ustar00rootroot00000000000000--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 MessageFoo" php-stomp-1.0.5/stomp-1.0.5/tests/009-readFrame/005.phpt000066400000000000000000000007011214745710500220100ustar00rootroot00000000000000--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 MessageFoo" php-stomp-1.0.5/stomp-1.0.5/tests/010-timeout/000077500000000000000000000000001214745710500204015ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/010-timeout/001.phpt000066400000000000000000000036151214745710500216030ustar00rootroot00000000000000--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()); // Set read timout with the first param as a string, supposed to trigger a warning var_dump($s->setReadTimeout('')); // Fourth test, read supposed to get the last value set : 10.5 var_dump($s->getReadTimeout()); // Set read timout with the second param as a string, supposed to trigger a warning var_dump($s->setReadTimeout(10, '')); // 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(null, null)); // 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) } Warning: Stomp::setReadTimeout() expects parameter 1 to be long, string given in %s on line %d NULL array(2) { ["sec"]=> int(10) ["usec"]=> int(5) } Warning: Stomp::setReadTimeout() expects parameter 2 to be long, string given in %s on line %d NULL array(2) { ["sec"]=> int(10) ["usec"]=> int(5) } NULL array(2) { ["sec"]=> int(0) ["usec"]=> int(0) } php-stomp-1.0.5/stomp-1.0.5/tests/010-timeout/002.phpt000066400000000000000000000040051214745710500215760ustar00rootroot00000000000000--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-- --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) } Warning: stomp_set_read_timeout() expects parameter 2 to be long, string given in %s on line %d NULL array(2) { ["sec"]=> int(10) ["usec"]=> int(5) } Warning: stomp_set_read_timeout() expects parameter 3 to be long, string given in %s on line %d NULL array(2) { ["sec"]=> int(10) ["usec"]=> int(5) } NULL array(2) { ["sec"]=> int(0) ["usec"]=> int(0) } php-stomp-1.0.5/stomp-1.0.5/tests/011-commit/000077500000000000000000000000001214745710500202045ustar00rootroot00000000000000php-stomp-1.0.5/stomp-1.0.5/tests/011-commit/001.phpt000066400000000000000000000021221214745710500213760ustar00rootroot00000000000000--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