diff options
| author | Sascha Schumann <sas@php.net> | 1999-09-11 23:47:16 +0000 |
|---|---|---|
| committer | Sascha Schumann <sas@php.net> | 1999-09-11 23:47:16 +0000 |
| commit | f040ce584d1509d61e96fa503b611e14685e71db (patch) | |
| tree | 30408a76ba71e54c1ad66c90c495bb93b5321335 | |
| parent | 9706aa1daa3008c1352cd53023355041136a0da5 (diff) | |
| download | php-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.stub | 1 | ||||
| -rw-r--r-- | ext/session/config.m4 | 19 | ||||
| -rw-r--r-- | ext/session/php_session.h | 7 | ||||
| -rw-r--r-- | ext/session/session.c | 20 | ||||
| -rw-r--r-- | ext/standard/Makefile.am | 2 | ||||
| -rw-r--r-- | ext/standard/url_scanner.c | 375 | ||||
| -rw-r--r-- | ext/standard/url_scanner.h | 6 | ||||
| -rw-r--r-- | ext/standard/url_scanner.re | 163 | ||||
| -rw-r--r-- | output.c | 21 |
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; +} @@ -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; } |
