Add stomp+SSL support

v1.1
Pierrick Charron 2009-10-31 20:34:03 +00:00
parent c030cb4e2a
commit 9182fffe6e
5 changed files with 116 additions and 11 deletions

View File

@ -5,6 +5,25 @@ 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

View File

@ -4,7 +4,7 @@
<channel>pecl.php.net</channel>
<summary>Stomp client extension</summary>
<description>
This extension allows php applications to comunicate with any Stomp compliant Message Brokers through easy object oriented and procedural interfaces.
This extension allows php applications to communicate with any Stomp compliant Message Brokers through easy object oriented and procedural interfaces.
</description>
<lead>
<name>Pierrick Charron</name>

View File

@ -373,7 +373,11 @@ PHP_FUNCTION(stomp_connect)
char *broker = NULL, *username = NULL, *password = NULL;
int broker_len = 0, username_len = 0, password_len = 0;
struct timeval tv;
php_url *url_parts;
php_url *url_parts;
#ifdef HAVE_STOMP_SSL
int use_ssl = 0;
#endif
tv.tv_sec = 2;
tv.tv_usec = 0;
@ -394,16 +398,30 @@ PHP_FUNCTION(stomp_connect)
php_url_free(url_parts);
return;
}
if (url_parts->scheme && strcmp(url_parts->scheme, "tcp") != 0) {
STOMP_ERROR(0, PHP_STOMP_ERR_INVALID_BROKER_URI_SCHEME);
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_new(url_parts->host, url_parts->port ? url_parts->port : 61613, STOMP_G(timeout_sec), STOMP_G(timeout_usec) TSRMLS_CC);
php_url_free(url_parts);
#if HAVE_STOMP_SSL
stomp->use_ssl = use_ssl;
#endif
if ((stomp->status = stomp_connect(stomp TSRMLS_CC))) {
stomp_frame_t *res;
stomp_frame_t frame = {0};

66
stomp.c
View File

@ -50,6 +50,11 @@ stomp_t *stomp_new(const char *host, unsigned short port, long timeout_sec, long
stomp->timeout_usec = timeout_usec;
stomp->session = NULL;
#if HAVE_STOMP_SSL
stomp->ssl_handle = NULL;
stomp->use_ssl = 0;
#endif
return stomp;
}
/* }}} */
@ -102,6 +107,32 @@ int stomp_connect(stomp_t *stomp TSRMLS_DC)
FD_SET(stomp->fd, &rfds);
if (select(stomp->fd + 1, NULL, &rfds, NULL, &tv) > 0) {
#if HAVE_STOMP_SSL
if (stomp->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);
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);
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);
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);
@ -120,6 +151,11 @@ int stomp_close(stomp_t *stomp TSRMLS_DC)
}
if (stomp->fd != -1) {
#if HAVE_STOMP_SSL
if(stomp->ssl_handle) {
SSL_shutdown(stomp->ssl_handle);
}
#endif
closesocket(stomp->fd);
}
if (stomp->host) {
@ -182,9 +218,19 @@ int stomp_send(stomp_t *stomp, stomp_frame_t *frame TSRMLS_DC)
smart_str_appends(&buf, frame->body);
}
if (-1 == send(stomp->fd, buf.c, buf.len, 0) || -1 == send(stomp->fd, "\0\n", 2, 0)) {
return 0;
#ifdef HAVE_STOMP_SSL
if (stomp->use_ssl) {
if (-1 == SSL_write(stomp->ssl_handle, buf.c, buf.len) || -1 == SSL_write(stomp->ssl_handle, "\0\n", 2)) {
return 0;
}
} else {
#endif
if (-1 == send(stomp->fd, buf.c, buf.len, 0) || -1 == send(stomp->fd, "\0\n", 2, 0)) {
return 0;
}
#ifdef HAVE_STOMP_SSL
}
#endif
smart_str_free(&buf);
@ -192,6 +238,22 @@ int stomp_send(stomp_t *stomp, stomp_frame_t *frame TSRMLS_DC)
}
/* }}} */
/* {{{ stomp_recv
*/
int stomp_recv(stomp_t *stomp, char *msg, size_t length)
{
#if HAVE_STOMP_SSL
if(stomp->use_ssl) {
return SSL_read(stomp->ssl_handle, msg, length);
} else {
#endif
return recv(stomp->fd, msg, length, 0);
#if HAVE_STOMP_SSL
}
#endif
}
/* }}} */
/* {{{ stomp_read_buffer
*/
static int stomp_read_buffer(stomp_t *stomp, char **data)

10
stomp.h
View File

@ -23,6 +23,10 @@
#include "php_network.h"
#if HAVE_STOMP_SSL
#include <openssl/ssl.h>
#endif
#define STOMP_BUFSIZE 4096
#define INIT_STOMP_FRAME(f) \
@ -31,8 +35,6 @@
ALLOC_HASHTABLE(f->headers); \
zend_hash_init(f->headers, 0, NULL, NULL, 0);
#define stomp_recv(c,b,l) recv((c)->fd, b, l, 0)
typedef struct _stomp {
php_socket_t fd;
php_sockaddr_storage localaddr;
@ -44,6 +46,10 @@ typedef struct _stomp {
long timeout_sec;
long timeout_usec;
char *session;
#if HAVE_STOMP_SSL
SSL *ssl_handle;
int use_ssl;
#endif
} stomp_t;
typedef struct _stomp_frame {