| Portions copyright the PHP group. |
+----------------------------------------------------------------------+
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "php.h"
#include "php_ini.h"
#include "php_msession.h"
#include "ext/standard/info.h"
#include "ext/session/php_session.h"
+
/* Macros and such */
#ifndef TRUE
#define TRUE 1
/* Uncomment to get debugging messages */
/* #define ERR_DEBUG */
+/* Uncomment for conections which are persistent for a process
+ * This will be faster but allocates a thread in the msession
+ * daemon.
+ * Pros: No reconnect overhead.
+ * cons: Msession maintains a thread per connection.
+ */
+/* #define PERSISTENT_CONN */
#ifdef ERR_DEBUG
#define ELOG( str ) php_log_err( str )
#define IFCONNECT_ENDVAL(V) } else { php_error(E_WARNING, s_szNoInit); return V; }
#define IFCONNECT_END } else { php_error(E_WARNING, s_szNoInit); RETURN_FALSE; }
+#ifndef HAVE_PHP_SESSION
+#error HAVE_PHP_SESSION not defined
+#endif
+
/* Test if session module contains custom sesson ID patch */
#ifdef PHP_SESSION_API
#if (PHP_SESSION_API >= 20020330)
/* This sets the PHP API version used in the file. */
/* If this module does not compile on the version of PHP you are using, look for */
/* this value in Zend/zend_modules.h, and set appropriately */
-
#if (ZEND_MODULE_API_NO <= 20001222)
#define PHP_4_0
#define TSRMLS_CC
PHP_RSHUTDOWN_FUNCTION(msession)
{
+#ifndef PERSISTENT_CONN
if(s_conn)
{
CloseReqConn(s_conn);
FreeRequestBuffer(s_reqb);
s_reqb=NULL;
}
+#endif
return SUCCESS;
}
php_info_print_table_end();
}
+/* The PHP Version of DoRequest */
+/* Manages connections that have been disconnected */
+int PHPDoRequest(void **pconn, REQB **ppreq)
+{
+ void *conn = *pconn;
+ int stat = (*ppreq)->req.stat;
+ int param = (*ppreq)->req.param;
+
+ int result = DoRequest(conn, ppreq);
+
+ // Server closed the connection!
+ if((*ppreq)->req.stat == REQ_ERR && (result == REQE_BADCONN || result == REQE_NOSEND))
+ {
+ // In the case of a bad socket, this should be
+ // all that changs!
+ (*ppreq)->req.stat = stat;
+ (*ppreq)->req.param = param;
+ ELOG("Connection was closed by server");
+ if(ReopenReqConn(conn))
+ result = DoRequest(*pconn, ppreq);
+ }
+#ifdef ERR_DEBUG
+ if((*ppreq)->req.stat == REQ_ERR && (result == REQE_BADCONN || result == REQE_NOSEND))
+ ELOG("Socket reports closed");
+#endif
+ return result;
+}
+
int PHPMsessionConnect(const char *szhost, int nport)
{
+ int fNewHost=FALSE;
TSRMLS_FETCH();
+
if(!s_reqb)
s_reqb = AllocateRequestBuffer(2048);
if(!s_reqb) // no buffer, it won't work!
return 0;
-
- if(s_conn)
- {
- CloseReqConn(s_conn);
- php_log_err("Call to connect with non-null s_conn" TSRMLS_CC);
- }
+
if(strcmp(s_szhost, szhost))
{
if(s_szhost != s_szdefhost)
free(s_szhost);
s_szhost = strdup(szhost);
+ fNewHost = TRUE;
}
- if(nport)
+ if(nport && nport != s_port)
+ {
+ fNewHost = TRUE;
s_port = nport;
+ }
+
+#ifndef PERSISTENT_CONN
+ ELOG("PHPMsessionConnect:old");
+ if(s_conn)
+ {
+ CloseReqConn(s_conn);
+ php_log_err("Call to connect with non-null s_conn" TSRMLS_CC);
+ }
s_conn = OpenReqConn(s_szhost, s_port);
+#else
+ ELOG("PHPMsessionConnect:new");
+ if(s_conn && fNewHost)
+ {
+ ELOG("Closing old connection, opening new");
+ CloseReqConn(s_conn);
+ s_conn = NULL;
+ }
+ if(!s_conn)
+ s_conn = OpenReqConn(s_szhost, s_port);
+#ifdef ERR_DEBUG
+ else
+ {
+ ELOG("Reusing old connection");
+ }
+#endif
+#endif
+
#ifdef ERR_DEBUG
{
void PHPMsessionDisconnect()
{
+#ifndef PERSISTENT_CONN
if(s_conn)
{
CloseReqConn(s_conn);
FreeRequestBuffer(s_reqb);
s_reqb = NULL;
}
+#endif
}
char *PHPMsessionGetData(const char *session)
IFCONNECT_BEGIN
FormatRequest(&s_reqb, REQ_DATAGET, session,"","",0);
- DoRequest(s_conn, &s_reqb);
+ PHPDoRequest(&s_conn, &s_reqb);
if(s_reqb->req.stat==REQ_OK)
ret = safe_estrdup(s_reqb->req.datum);
}
int PHPMsessionSetData(const char *session, const char *data)
{
-
IFCONNECT_BEGIN
int ret=0;
FormatRequest(&s_reqb, REQ_DATASET, session,"",data,0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
ret = (s_reqb->req.stat==REQ_OK);
if(s_reqb->req.stat!=REQ_OK)
php_error(E_WARNING, s_szErrFmt, ReqbErr(s_reqb));
IFCONNECT_ENDVAL(0)
}
-
int PHPMsessionDestroy(const char *session)
{
IFCONNECT_BEGIN
int ret=0;
FormatRequest(&s_reqb, REQ_DROP, session, "","",0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
ret = (s_reqb->req.stat==REQ_OK);
if(s_reqb->req.stat!=REQ_OK)
php_error(E_WARNING, s_szErrFmt, ReqbErr(s_reqb));
int count;
FormatRequest(&s_reqb, REQ_COUNT, "", "","",0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
count = (s_reqb->req.stat == REQ_OK) ? s_reqb->req.param : 0;
convert_to_string_ex(session);
szsession = Z_STRVAL_PP(session);
FormatRequest(&s_reqb, REQ_CREATE, szsession, "","",0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
if(s_reqb->req.stat==REQ_OK)
{
RETURN_TRUE;
convert_to_string_ex(session);
szsession = Z_STRVAL_PP(session);
FormatRequest(&s_reqb, REQ_SLOCK, szsession, "","",0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
if(s_reqb->req.stat==REQ_OK)
{
}
}
FormatRequest(&s_reqb, REQ_CTL, szsession, "","",fn);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
if(s_reqb->req.stat==REQ_OK)
{
convert_to_long_ex(key);
lkey = Z_LVAL_PP(key);
FormatRequest(&s_reqb, REQ_SUNLOCK, szsession, "","",lkey);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
if(s_reqb->req.stat==REQ_OK)
{
szvalue = Z_STRVAL_PP(value);
FormatRequest(&s_reqb, REQ_SETVAL, szsession, szname, szvalue, 0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
if(s_reqb->req.stat==REQ_OK)
{
szvalue = Z_STRVAL_PP(value);
FormatRequest(&s_reqb, REQ_GETVAL, szsession, szname, szvalue,0);
- DoRequest(s_conn, &s_reqb);
+ PHPDoRequest(&s_conn, &s_reqb);
if(s_reqb->req.stat==REQ_OK)
{
val = Z_LVAL_PP(param);
FormatRequest(&s_reqb, REQ_UNIQ,"", "", "",val);
- DoRequest(s_conn, &s_reqb);
+ PHPDoRequest(&s_conn, &s_reqb);
if(s_reqb->req.stat==REQ_OK)
{
val = Z_LVAL_PP(param);
FormatRequest(&s_reqb, REQ_RANDSTR,"", "", "",val);
- DoRequest(s_conn, &s_reqb);
+ PHPDoRequest(&s_conn, &s_reqb);
if(s_reqb->req.stat==REQ_OK)
{
szvalue = Z_STRVAL_PP(value);
FormatRequest(&s_reqb, REQ_FIND, "", szname, szvalue,0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
if(s_reqb->req.stat==REQ_OK && s_reqb->req.param)
{
{
IFCONNECT_BEGIN
FormatRequest(&s_reqb, REQ_LIST, "", "", "",0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
if(s_reqb->req.stat==REQ_OK && s_reqb->req.param)
{
convert_to_string_ex(session);
szsession = Z_STRVAL_PP(session);
FormatRequest(&s_reqb, REQ_GETALL, szsession, "", "",0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
array_init(return_value);
ELOG("FormatMulti");
FormatRequestMulti(&s_reqb, REQ_SETVAL, Z_STRVAL_PP(session), countpair, pairs,0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
if(s_reqb->req.stat != REQ_OK)
php_error(E_WARNING, s_szErrFmt, ReqbErr(s_reqb));
}
convert_to_string_ex(name);
FormatRequest(&s_reqb, REQ_LISTVAR, "", Z_STRVAL_PP(name), "",0);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
array_init(return_value);
}
convert_to_string_ex(session);
FormatRequest(&s_reqb, REQ_TIMEOUT, Z_STRVAL_PP(session), "","",timeout);
- DoRequest(s_conn,&s_reqb);
+ PHPDoRequest(&s_conn,&s_reqb);
if(s_reqb->req.stat == REQ_OK)
{
convert_to_string_ex(name);
FormatRequest(&s_reqb, REQ_INC, Z_STRVAL_PP(session), Z_STRVAL_PP(name),0,0);
- DoRequest(s_conn, &s_reqb);
+ PHPDoRequest(&s_conn, &s_reqb);
if(s_reqb->req.stat==REQ_OK)
{
ret = atoi(Z_STRVAL_PP(val));
FormatRequest(&s_reqb, REQ_PLUGIN, Z_STRVAL_PP(session), Z_STRVAL_PP(val), param ? Z_STRVAL_PP(param) : "",ret);
- DoRequest(s_conn, &s_reqb);
+ PHPDoRequest(&s_conn, &s_reqb);
if(s_reqb->req.stat==REQ_OK && s_reqb->req.len)
{
}
FormatRequestStrings(&s_reqb, REQ_CALL, NULL , n, strings);
- DoRequest(s_conn, &s_reqb);
+ PHPDoRequest(&s_conn, &s_reqb);
if(s_reqb->req.stat==REQ_OK && s_reqb->req.len)
{
PS_OPEN_FUNC(msession)
{
+ int port;
+ int len = strlen(save_path)+1;
+ char * path = alloca(len);
+ char * szport;
+
+ strcpy(path, save_path);
+
+ szport = strchr(path, ':');
+
+ if(szport)
+ {
+ *szport++=0;
+ port = atoi(szport);
+ }
+ else
+ {
+ port = s_port;
+ }
+
ELOG( "ps_open_msession");
PS_SET_MOD_DATA((void *)1); // session.c needs a non-zero here!
- return PHPMsessionConnect(save_path, 8086) ? SUCCESS : FAILURE;
+ return PHPMsessionConnect(path, port) ? SUCCESS : FAILURE;
}
PS_CLOSE_FUNC(msession)
{
ELOG("Should create a new session");
FormatRequest(&s_reqb, REQ_UNIQ,"", "", "",SID_LEN);
- DoRequest(s_conn, &s_reqb);
+ PHPDoRequest(&s_conn, &s_reqb);
if(s_reqb->req.stat==REQ_OK)
{