summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Schumann <sas@php.net>1999-09-11 23:47:16 +0000
committerSascha Schumann <sas@php.net>1999-09-11 23:47:16 +0000
commitf040ce584d1509d61e96fa503b611e14685e71db (patch)
tree30408a76ba71e54c1ad66c90c495bb93b5321335
parent9706aa1daa3008c1352cd53023355041136a0da5 (diff)
downloadphp-git-f040ce584d1509d61e96fa503b611e14685e71db.tar.gz
add transparent session id propagation
this uses a custom scanner which detects relative URIs and changes them appropiately. must be explicitly enabled with --enable-trans-sid (normal case is not affected, since session_adapt_uris defaults to void statement. Compiler should eliminate dead code in output.c then.)
-rw-r--r--ext/session/config.h.stub1
-rw-r--r--ext/session/config.m419
-rw-r--r--ext/session/php_session.h7
-rw-r--r--ext/session/session.c20
-rw-r--r--ext/standard/Makefile.am2
-rw-r--r--ext/standard/url_scanner.c375
-rw-r--r--ext/standard/url_scanner.h6
-rw-r--r--ext/standard/url_scanner.re163
-rw-r--r--output.c21
9 files changed, 605 insertions, 9 deletions
diff --git a/ext/session/config.h.stub b/ext/session/config.h.stub
index 4dc5ec115c..24abf8b280 100644
--- a/ext/session/config.h.stub
+++ b/ext/session/config.h.stub
@@ -1,3 +1,4 @@
/* define if you want to use the session extension */
+#undef TRANS_SID
#undef HAVE_LIBMM
diff --git a/ext/session/config.m4 b/ext/session/config.m4
index ac39c53cf4..8db20b3324 100644
--- a/ext/session/config.m4
+++ b/ext/session/config.m4
@@ -2,8 +2,7 @@ dnl $Id$
dnl config.m4 for extension session
dnl don't forget to call PHP_EXTENSION(session)
-
-MM_RESULT=no
+RESULT=no
AC_MSG_CHECKING(for mm support)
AC_ARG_WITH(mm,
[ --with-mm[=DIR] Include mm support],
@@ -22,10 +21,22 @@ AC_ARG_WITH(mm,
AC_ADD_LIBRARY_WITH_PATH(mm, $MM_DIR/lib)
AC_ADD_INCLUDE($MM_DIR/include)
AC_DEFINE(HAVE_LIBMM, 1)
- MM_RESULT=yes
+ RESULT=yes
PHP_EXTENSION(ps_mm)
fi
])
-AC_MSG_RESULT($MM_RESULT)
+AC_MSG_RESULT($RESULT)
+
+RESULT=no
+AC_MSG_CHECKING(whether to enable transparent session id propagation)
+AC_ARG_ENABLE(trans-sid,
+[ --enable-trans-sid Enable transparent session id propagation],
+[
+ if test "$enableval" = "yes" ; then
+ AC_DEFINE(TRANS_SID, 1)
+ RESULT=yes
+ fi
+])
+AC_MSG_RESULT($RESULT)
PHP_EXTENSION(session)
diff --git a/ext/session/php_session.h b/ext/session/php_session.h
index e54e8e2b85..62948d44d5 100644
--- a/ext/session/php_session.h
+++ b/ext/session/php_session.h
@@ -78,6 +78,7 @@ typedef struct {
char *entropy_file;
int entropy_length;
int lifetime;
+ zend_bool define_sid;
ps_module *mod;
void *mod_data;
HashTable vars;
@@ -141,4 +142,10 @@ typedef struct ps_serializer_struct {
#define PS_SERIALIZER_ENTRY(x) \
{ #x, _ps_srlzr_encode_##x, _ps_srlzr_decode_##x }
+#ifdef TRANS_SID
+void session_adapt_uris(const char *, uint, char **, uint *);
+#else
+#define session_adapt_uris(a,b) do { } while(0)
+#endif
+
#endif
diff --git a/ext/session/session.c b/ext/session/session.c
index fc727bfa00..36957c1340 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -39,6 +39,7 @@
#include "ext/standard/php3_var.h"
#include "ext/standard/datetime.h"
#include "ext/standard/php_lcg.h"
+#include "ext/standard/url_scanner.h"
#ifdef ZTS
int ps_globals_id;
@@ -504,6 +505,7 @@ static void _php_session_start(PSLS_D)
} else {
REGISTER_STRING_CONSTANT("SID", empty_string, 0);
}
+ PS(define_sid) = define_sid;
PS(nr_open_sessions)++;
@@ -528,7 +530,6 @@ static void _php_session_destroy(PSLS_D)
PS(mod)->destroy(&PS(mod_data), PS(id));
php_rshutdown_session_globals(PSLS_C);
php_rinit_session_globals(PSLS_C);
- PS(nr_open_sessions)--;
}
/* {{{ proto string session_name([string newname])
@@ -756,6 +757,22 @@ PHP_FUNCTION(session_destroy)
}
/* }}} */
+#ifdef TRANS_SID
+void session_adapt_uris(const char *src, uint srclen, char **new, uint *newlen)
+{
+ char *data;
+ size_t len;
+ char buf[512];
+ PSLS_FETCH();
+
+ if(PS(define_sid) && PS(nr_open_sessions) > 0) {
+ snprintf(buf, sizeof(buf), "%s=%s", PS(session_name), PS(id));
+ data = url_adapt(src, srclen, buf, &len);
+ *new = data;
+ *newlen = len;
+ }
+}
+#endif
/* {{{ proto session_unset()
Unset all registered variables */
@@ -784,6 +801,7 @@ static void php_rinit_session_globals(PSLS_D)
_php_find_ps_serializer(INI_STR("session.serialize_handler") PSLS_CC);
zend_hash_init(&PS(vars), 0, NULL, NULL, 0);
+ PS(define_sid) = 0;
PS(save_path) = estrdup(INI_STR("session.save_path"));
PS(session_name) = estrdup(INI_STR("session.name"));
PS(entropy_file) = estrdup(INI_STR("session.entropy_file"));
diff --git a/ext/standard/Makefile.am b/ext/standard/Makefile.am
index a0ca94e0aa..db72a28491 100644
--- a/ext/standard/Makefile.am
+++ b/ext/standard/Makefile.am
@@ -8,7 +8,7 @@ libphpext_standard_a_SOURCES=\
pack.c pageinfo.c rand.c reg.c soundex.c string.c \
syslog.c type.c uniqid.c url.c iptc.c var.c quot_print.c \
cyr_convert.c flock_compat.c crypt.c dl.c head.c post.c \
- parsedate.y lcg.c
+ parsedate.y lcg.c url_scanner.c
#number.o: number.c
# $(CC) $(CFLAGS) -w@WARNING_LEVEL@ -c $< -o $@
diff --git a/ext/standard/url_scanner.c b/ext/standard/url_scanner.c
new file mode 100644
index 0000000000..4e191b21cc
--- /dev/null
+++ b/ext/standard/url_scanner.c
@@ -0,0 +1,375 @@
+/* Generated by re2c 0.5 on Sun Sep 12 00:56:23 1999 */
+#line 1 "xx.re"
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define YYCTYPE char
+#define YYCURSOR state->crs
+#define YYLIMIT state->end
+#define YYMARKER state->ptr
+#define YYFILL(n)
+
+typedef enum {
+ INITIAL,
+ REF
+} state;
+
+typedef struct {
+ state state;
+ const char *crs;
+ const char *end;
+ const char *ptr;
+ const char *start;
+ char *target;
+ size_t targetsize;
+ const char *data;
+} lexdata;
+
+#define FINISH { catchup(state); goto finish; }
+
+#define BEGIN(x) \
+ switch(state->state) { \
+ case INITIAL: \
+ catchup(state); \
+ break; \
+ case REF: \
+ screw_url(state); \
+ break; \
+ } \
+ state->state = x; \
+ state->start = state->crs; \
+ goto nextiter
+
+#define ATTACH(s, n) { \
+ size_t _newlen = state->targetsize + n; \
+ state->target = realloc(state->target, _newlen + 1); \
+ memcpy(state->target + state->targetsize, s, n); \
+ state->targetsize = _newlen; \
+ state->target[_newlen] = '\0'; \
+ }
+
+#define URLLEN 512
+
+static void screw_url(lexdata *state)
+{
+ char *url;
+ int len;
+ char buf[URLLEN];
+ const char *p, *q;
+ char c;
+
+ /* search outer limits for URI */
+ for(p = state->start; p < state->crs && (c = *p); p++)
+ if(c != '"' && c != ' ') break;
+
+ /*
+ * we look at q-1, because q points to the character behind the last
+ * character we are going to copy and the decision is based on that last
+ * character
+ */
+
+ for(q = state->crs; q > state->start && (c = *(q-1)); q--)
+ if(c != '"' && c != ' ') break;
+
+ /* attach beginning */
+
+ ATTACH(state->start, p-state->start);
+
+ /* copy old URI */
+ len = q - p;
+ url = malloc(len + 1);
+ memcpy(url, p, len);
+ url[len] = '\0';
+
+ /* construct new URI */
+ len = snprintf(buf, sizeof(buf), "%s%c%s", url,
+ memchr(state->start, '?', len) ? '&' : '?',
+ state->data);
+ free(url);
+
+ /* attach new URI */
+ ATTACH(buf, len);
+
+ /* attach rest */
+ ATTACH(q, state->crs - q);
+}
+
+static void catchup(lexdata *state)
+{
+ ATTACH(state->start, (state->crs - state->start));
+}
+
+#line 115
+
+
+static void url_scanner(lexdata *state)
+{
+ while(state->crs < state->end) {
+
+ switch(state->state) {
+ case INITIAL:
+{
+ YYCTYPE yych;
+ unsigned int yyaccept;
+ goto yy0;
+yy1: ++YYCURSOR;
+yy0:
+ if((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
+ yych = *YYCURSOR;
+ switch(yych){
+ case '\000': goto yy7;
+ case '<': goto yy2;
+ default: goto yy4;
+ }
+yy2: yych = *++YYCURSOR;
+ switch(yych){
+ case 'A': case 'a': goto yy9;
+ case 'F': case 'f': goto yy10;
+ default: goto yy3;
+ }
+yy3:yy4: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy5: switch(yych){
+ case '\000': case '<': goto yy6;
+ default: goto yy4;
+ }
+yy6:
+#line 126
+ { BEGIN(INITIAL); }
+yy7: yych = *++YYCURSOR;
+yy8:
+#line 127
+ { FINISH; }
+yy9: yych = *++YYCURSOR;
+ switch(yych){
+ case 'H': case 'h': goto yy3;
+ default: goto yy25;
+ }
+yy10: yych = *++YYCURSOR;
+ switch(yych){
+ case 'R': case 'r': goto yy11;
+ default: goto yy3;
+ }
+yy11: yych = *++YYCURSOR;
+ switch(yych){
+ case 'A': case 'a': goto yy12;
+ default: goto yy3;
+ }
+yy12: yych = *++YYCURSOR;
+ switch(yych){
+ case 'M': case 'm': goto yy13;
+ default: goto yy3;
+ }
+yy13: yych = *++YYCURSOR;
+ switch(yych){
+ case 'E': case 'e': goto yy14;
+ default: goto yy3;
+ }
+yy14: yych = *++YYCURSOR;
+ switch(yych){
+ case 'S': case 's': goto yy3;
+ default: goto yy16;
+ }
+yy15: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy16: switch(yych){
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy15;
+ case 'S': case 's': goto yy17;
+ default: goto yy3;
+ }
+yy17: yych = *++YYCURSOR;
+ switch(yych){
+ case 'R': case 'r': goto yy18;
+ default: goto yy3;
+ }
+yy18: yych = *++YYCURSOR;
+ switch(yych){
+ case 'C': case 'c': goto yy19;
+ default: goto yy3;
+ }
+yy19: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy20: switch(yych){
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy19;
+ case '=': goto yy21;
+ default: goto yy3;
+ }
+yy21: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy22: switch(yych){
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy21;
+ default: goto yy23;
+ }
+yy23:
+#line 124
+ { BEGIN(REF); }
+yy24: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy25: switch(yych){
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy24;
+ case 'H': case 'h': goto yy26;
+ default: goto yy3;
+ }
+yy26: yych = *++YYCURSOR;
+ switch(yych){
+ case 'R': case 'r': goto yy27;
+ default: goto yy3;
+ }
+yy27: yych = *++YYCURSOR;
+ switch(yych){
+ case 'E': case 'e': goto yy28;
+ default: goto yy3;
+ }
+yy28: yych = *++YYCURSOR;
+ switch(yych){
+ case 'F': case 'f': goto yy29;
+ default: goto yy3;
+ }
+yy29: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy30: switch(yych){
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy29;
+ case '=': goto yy31;
+ default: goto yy3;
+ }
+yy31: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy32: switch(yych){
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy31;
+ default: goto yy33;
+ }
+yy33:
+#line 125
+ { BEGIN(REF); }
+}
+#line 128
+
+ break;
+ case REF:
+{
+ YYCTYPE yych;
+ unsigned int yyaccept;
+ goto yy34;
+yy35: ++YYCURSOR;
+yy34:
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ switch(yych){
+ case '\000': case '#': case '>': goto yy36;
+ case '\t': case '\v':
+ case '\f': case ' ': case '"': goto yy37;
+ case ':': goto yy42;
+ default: goto yy39;
+ }
+yy36:yy37: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy38: switch(yych){
+ case '\000': case '"':
+ case '#': case '>': goto yy36;
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy37;
+ case ':': goto yy42;
+ default: goto yy39;
+ }
+yy39: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy40: switch(yych){
+ case '\000': case '>': goto yy41;
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy48;
+ case '"': goto yy50;
+ case '#': goto yy51;
+ case ':': goto yy42;
+ default: goto yy39;
+ }
+yy41:
+#line 132
+ { BEGIN(INITIAL); }
+yy42: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy43: switch(yych){
+ case '\000': case '#': case '>': goto yy44;
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy45;
+ case '"': goto yy47;
+ default: goto yy42;
+ }
+yy44:
+#line 134
+ {
+ /* don't modify absolute links */
+ state->state = INITIAL; BEGIN(INITIAL);
+ }
+yy45: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy46: switch(yych){
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy45;
+ case '"': goto yy47;
+ default: goto yy44;
+ }
+yy47: yych = *++YYCURSOR;
+ goto yy44;
+yy48: ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy49: switch(yych){
+ case '\t': case '\v':
+ case '\f': case ' ': goto yy48;
+ case '"': goto yy50;
+ default: goto yy41;
+ }
+yy50: yych = *++YYCURSOR;
+ goto yy41;
+yy51: yych = *++YYCURSOR;
+yy52: YYCURSOR -= 1;
+#line 133
+ { BEGIN(INITIAL); }
+}
+#line 138
+
+ break;
+ }
+nextiter:
+ }
+finish:
+}
+
+char *url_adapt(const char *src, size_t srclen, const char *data, size_t *newlen)
+{
+ lexdata state;
+
+ state.state = INITIAL;
+ state.start = state.crs = src;
+ state.end = src + srclen;
+ state.ptr = NULL;
+ state.target = NULL;
+ state.targetsize = 0;
+ state.data = data;
+
+ url_scanner(&state);
+
+ if(newlen) *newlen = state.targetsize;
+
+ return state.target;
+}
diff --git a/ext/standard/url_scanner.h b/ext/standard/url_scanner.h
new file mode 100644
index 0000000000..4779cc10a2
--- /dev/null
+++ b/ext/standard/url_scanner.h
@@ -0,0 +1,6 @@
+#ifndef URI_SCANNER_H
+#define URI_SCANNER_H
+
+char *url_adapt(const char *src, size_t srclen, const char *data, size_t *newlen);
+
+#endif
diff --git a/ext/standard/url_scanner.re b/ext/standard/url_scanner.re
new file mode 100644
index 0000000000..4436862e7f
--- /dev/null
+++ b/ext/standard/url_scanner.re
@@ -0,0 +1,163 @@
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define YYCTYPE char
+#define YYCURSOR state->crs
+#define YYLIMIT state->end
+#define YYMARKER state->ptr
+#define YYFILL(n)
+
+typedef enum {
+ INITIAL,
+ REF
+} state;
+
+typedef struct {
+ state state;
+ const char *crs;
+ const char *end;
+ const char *ptr;
+ const char *start;
+ char *target;
+ size_t targetsize;
+ const char *data;
+} lexdata;
+
+#define FINISH { catchup(state); goto finish; }
+
+#define BEGIN(x) \
+ switch(state->state) { \
+ case INITIAL: \
+ catchup(state); \
+ break; \
+ case REF: \
+ screw_url(state); \
+ break; \
+ } \
+ state->state = x; \
+ state->start = state->crs; \
+ goto nextiter
+
+#define ATTACH(s, n) { \
+ size_t _newlen = state->targetsize + n; \
+ state->target = realloc(state->target, _newlen + 1); \
+ memcpy(state->target + state->targetsize, s, n); \
+ state->targetsize = _newlen; \
+ state->target[_newlen] = '\0'; \
+ }
+
+#define URLLEN 512
+
+static void screw_url(lexdata *state)
+{
+ char *url;
+ int len;
+ char buf[URLLEN];
+ const char *p, *q;
+ char c;
+
+ /* search outer limits for URI */
+ for(p = state->start; p < state->crs && (c = *p); p++)
+ if(c != '"' && c != ' ') break;
+
+ /*
+ * we look at q-1, because q points to the character behind the last
+ * character we are going to copy and the decision is based on that last
+ * character
+ */
+
+ for(q = state->crs; q > state->start && (c = *(q-1)); q--)
+ if(c != '"' && c != ' ') break;
+
+ /* attach beginning */
+
+ ATTACH(state->start, p-state->start);
+
+ /* copy old URI */
+ len = q - p;
+ url = malloc(len + 1);
+ memcpy(url, p, len);
+ url[len] = '\0';
+
+ /* construct new URI */
+ len = snprintf(buf, sizeof(buf), "%s%c%s", url,
+ memchr(state->start, '?', len) ? '&' : '?',
+ state->data);
+ free(url);
+
+ /* attach new URI */
+ ATTACH(buf, len);
+
+ /* attach rest */
+ ATTACH(q, state->crs - q);
+}
+
+static void catchup(lexdata *state)
+{
+ ATTACH(state->start, (state->crs - state->start));
+}
+
+/*!re2c
+all = [\001-\377];
+eof = [\000];
+ws = [ \t\v\f];
+A = [aA];
+C = [cC];
+E = [eE];
+F = [fF];
+H = [hH];
+M = [mM];
+R = [rR];
+S = [sS];
+*/
+
+static void url_scanner(lexdata *state)
+{
+ while(state->crs < state->end) {
+
+ switch(state->state) {
+ case INITIAL:
+/*!re2c
+ "<" F R A M E ws+ S R C ws* "=" ws* { BEGIN(REF); }
+ "<" A ws+ H R E F ws* "=" ws* { BEGIN(REF); }
+ (all\[<])+ { BEGIN(INITIAL); }
+ eof { FINISH; }
+*/
+ break;
+ case REF:
+/*!re2c
+ ["]? ws* (all\[> \t\v\f":#])+ ws* ["]? { BEGIN(INITIAL); }
+ ["]? ws* (all\[> \t\v\f":#])+/[#] { BEGIN(INITIAL); }
+ ["]? ws* (all\[> \t\v\f"#])+ ws* ["]? {
+ /* don't modify absolute links */
+ state->state = INITIAL; BEGIN(INITIAL);
+ }
+*/
+ break;
+ }
+nextiter:
+ }
+finish:
+}
+
+char *url_adapt(const char *src, size_t srclen, const char *data, size_t *newlen)
+{
+ lexdata state;
+
+ state.state = INITIAL;
+ state.start = state.crs = src;
+ state.end = src + srclen;
+ state.ptr = NULL;
+ state.target = NULL;
+ state.targetsize = 0;
+ state.data = data;
+
+ url_scanner(&state);
+
+ if(newlen) *newlen = state.targetsize;
+
+ return state.target;
+}
diff --git a/output.c b/output.c
index 7a3037c0cf..3739d41d9e 100644
--- a/output.c
+++ b/output.c
@@ -20,6 +20,7 @@
#include "php.h"
#include "ext/standard/head.h"
+#include "ext/session/php_session.h"
#include "SAPI.h"
/* output functions */
@@ -189,17 +190,31 @@ static int zend_ub_body_write_no_header(const char *str, uint str_length)
static int zend_ub_body_write(const char *str, uint str_length)
{
+ char *newstr = NULL;
+ uint new_length;
+ int result = 0;
SLS_FETCH();
if (SG(request_info).headers_only) {
zend_bailout();
}
if (php3_header()) {
+ session_adapt_uris(str, str_length, &newstr, &new_length);
+
+ if (newstr) {
+ str = newstr;
+ str_length = new_length;
+ }
+
zend_body_write = zend_ub_body_write_no_header;
- return zend_header_write(str, str_length);
- } else {
- return 0;
+ result = zend_header_write(str, str_length);
+
+ if (newstr) {
+ free(newstr);
+ }
}
+
+ return result;
}